From e76ca38810f50f6c2d42c09c51a95d3540c3b007 Mon Sep 17 00:00:00 2001 From: chriswmackey Date: Thu, 12 Dec 2024 01:12:44 +0000 Subject: [PATCH] deploy: update docs --- .nojekyll | 1 + README.md | 1 + docs/.buildinfo | 4 + docs/.doctrees/cli/index.doctree | Bin 0 -> 3660 bytes docs/.doctrees/cli/install.doctree | Bin 0 -> 7903 bytes docs/.doctrees/cli/simulate.doctree | Bin 0 -> 30430 bytes docs/.doctrees/cli/translate.doctree | Bin 0 -> 139216 bytes docs/.doctrees/dragonfly_energy.cli.doctree | Bin 0 -> 4208 bytes .../dragonfly_energy.cli.install.doctree | Bin 0 -> 3285 bytes .../dragonfly_energy.cli.simulate.doctree | Bin 0 -> 3310 bytes .../dragonfly_energy.cli.translate.doctree | Bin 0 -> 90106 bytes .../.doctrees/dragonfly_energy.config.doctree | Bin 0 -> 36880 bytes .../dragonfly_energy.des.connector.doctree | Bin 0 -> 49039 bytes docs/.doctrees/dragonfly_energy.des.doctree | Bin 0 -> 4183 bytes .../dragonfly_energy.des.ghe.doctree | Bin 0 -> 208303 bytes .../dragonfly_energy.des.junction.doctree | Bin 0 -> 38041 bytes .../dragonfly_energy.des.loop.doctree | Bin 0 -> 140663 bytes docs/.doctrees/dragonfly_energy.doctree | Bin 0 -> 4606 bytes .../dragonfly_energy.measure.doctree | Bin 0 -> 71880 bytes .../dragonfly_energy.opendss.colorobj.doctree | Bin 0 -> 75071 bytes ...dragonfly_energy.opendss.connector.doctree | Bin 0 -> 55599 bytes .../dragonfly_energy.opendss.doctree | Bin 0 -> 4925 bytes .../dragonfly_energy.opendss.junction.doctree | Bin 0 -> 38699 bytes .../dragonfly_energy.opendss.lib.doctree | Bin 0 -> 4251 bytes ...nfly_energy.opendss.lib.powerlines.doctree | Bin 0 -> 6681 bytes ...ly_energy.opendss.lib.transformers.doctree | Bin 0 -> 6829 bytes ...dragonfly_energy.opendss.lib.wires.doctree | Bin 0 -> 6439 bytes .../dragonfly_energy.opendss.network.doctree | Bin 0 -> 115149 bytes ...dragonfly_energy.opendss.powerline.doctree | Bin 0 -> 56362 bytes .../dragonfly_energy.opendss.result.doctree | Bin 0 -> 21358 bytes .../dragonfly_energy.opendss.road.doctree | Bin 0 -> 35190 bytes ...ragonfly_energy.opendss.substation.doctree | Bin 0 -> 41088 bytes ...agonfly_energy.opendss.transformer.doctree | Bin 0 -> 52772 bytes ...fly_energy.opendss.transformerprop.doctree | Bin 0 -> 55070 bytes .../dragonfly_energy.opendss.wire.doctree | Bin 0 -> 79631 bytes ...agonfly_energy.properties.building.doctree | Bin 0 -> 76712 bytes ...ragonfly_energy.properties.context.doctree | Bin 0 -> 39436 bytes .../dragonfly_energy.properties.doctree | Bin 0 -> 4284 bytes .../dragonfly_energy.properties.model.doctree | Bin 0 -> 78550 bytes ...dragonfly_energy.properties.room2d.doctree | Bin 0 -> 65396 bytes .../dragonfly_energy.properties.story.doctree | Bin 0 -> 44232 bytes docs/.doctrees/dragonfly_energy.reopt.doctree | Bin 0 -> 141127 bytes docs/.doctrees/dragonfly_energy.run.doctree | Bin 0 -> 63821 bytes .../.doctrees/dragonfly_energy.writer.doctree | Bin 0 -> 35305 bytes docs/.doctrees/environment.pickle | Bin 0 -> 1136581 bytes docs/.doctrees/index.doctree | Bin 0 -> 8045 bytes docs/.doctrees/modules.doctree | Bin 0 -> 2817 bytes docs/.nojekyll | 0 docs/README.md | 1 + .../dragonfly_energy/cli/translate.html | 2079 +++++ docs/_modules/dragonfly_energy/config.html | 1417 ++++ .../dragonfly_energy/des/connector.html | 1161 +++ docs/_modules/dragonfly_energy/des/ghe.html | 2218 ++++++ .../dragonfly_energy/des/junction.html | 1095 +++ docs/_modules/dragonfly_energy/des/loop.html | 2335 ++++++ docs/_modules/dragonfly_energy/measure.html | 1188 +++ .../dragonfly_energy/opendss/colorobj.html | 1310 ++++ .../dragonfly_energy/opendss/connector.html | 1194 +++ .../dragonfly_energy/opendss/junction.html | 1093 +++ .../opendss/lib/powerlines.html | 1015 +++ .../opendss/lib/transformers.html | 1016 +++ .../dragonfly_energy/opendss/lib/wires.html | 1010 +++ .../dragonfly_energy/opendss/network.html | 1828 +++++ .../dragonfly_energy/opendss/powerline.html | 1372 ++++ .../dragonfly_energy/opendss/result.html | 1121 +++ .../dragonfly_energy/opendss/road.html | 1093 +++ .../dragonfly_energy/opendss/substation.html | 1111 +++ .../dragonfly_energy/opendss/transformer.html | 1189 +++ .../opendss/transformerprop.html | 1298 ++++ .../dragonfly_energy/opendss/wire.html | 1503 ++++ .../dragonfly_energy/properties/building.html | 1568 ++++ .../dragonfly_energy/properties/context.html | 1191 +++ .../dragonfly_energy/properties/model.html | 1705 ++++ .../dragonfly_energy/properties/room2d.html | 1451 ++++ .../dragonfly_energy/properties/story.html | 1222 +++ docs/_modules/dragonfly_energy/reopt.html | 1691 ++++ docs/_modules/dragonfly_energy/run.html | 2361 ++++++ docs/_modules/dragonfly_energy/writer.html | 1357 ++++ docs/_modules/index.html | 1006 +++ docs/_sources/cli/index.rst.txt | 16 + docs/_sources/cli/install.rst.txt | 6 + docs/_sources/cli/simulate.rst.txt | 6 + docs/_sources/cli/translate.rst.txt | 6 + .../dragonfly_energy.cli.install.rst.txt | 7 + docs/_sources/dragonfly_energy.cli.rst.txt | 20 + .../dragonfly_energy.cli.simulate.rst.txt | 7 + .../dragonfly_energy.cli.translate.rst.txt | 7 + docs/_sources/dragonfly_energy.config.rst.txt | 7 + .../dragonfly_energy.des.connector.rst.txt | 7 + .../_sources/dragonfly_energy.des.ghe.rst.txt | 7 + .../dragonfly_energy.des.junction.rst.txt | 7 + .../dragonfly_energy.des.loop.rst.txt | 7 + docs/_sources/dragonfly_energy.des.rst.txt | 21 + .../_sources/dragonfly_energy.measure.rst.txt | 7 + .../dragonfly_energy.opendss.colorobj.rst.txt | 7 + ...dragonfly_energy.opendss.connector.rst.txt | 7 + .../dragonfly_energy.opendss.junction.rst.txt | 7 + ...nfly_energy.opendss.lib.powerlines.rst.txt | 7 + .../dragonfly_energy.opendss.lib.rst.txt | 20 + ...ly_energy.opendss.lib.transformers.rst.txt | 7 + ...dragonfly_energy.opendss.lib.wires.rst.txt | 7 + .../dragonfly_energy.opendss.network.rst.txt | 7 + ...dragonfly_energy.opendss.powerline.rst.txt | 7 + .../dragonfly_energy.opendss.result.rst.txt | 7 + .../dragonfly_energy.opendss.road.rst.txt | 7 + .../_sources/dragonfly_energy.opendss.rst.txt | 36 + ...ragonfly_energy.opendss.substation.rst.txt | 7 + ...agonfly_energy.opendss.transformer.rst.txt | 7 + ...fly_energy.opendss.transformerprop.rst.txt | 7 + .../dragonfly_energy.opendss.wire.rst.txt | 7 + ...agonfly_energy.properties.building.rst.txt | 7 + ...ragonfly_energy.properties.context.rst.txt | 7 + .../dragonfly_energy.properties.model.rst.txt | 7 + ...dragonfly_energy.properties.room2d.rst.txt | 7 + .../dragonfly_energy.properties.rst.txt | 22 + .../dragonfly_energy.properties.story.rst.txt | 7 + docs/_sources/dragonfly_energy.reopt.rst.txt | 7 + docs/_sources/dragonfly_energy.rst.txt | 33 + docs/_sources/dragonfly_energy.run.rst.txt | 7 + docs/_sources/dragonfly_energy.writer.rst.txt | 7 + docs/_sources/index.rst.txt | 43 + docs/_sources/modules.rst.txt | 7 + docs/_static/basic.css | 925 +++ .../css/bootstrap-responsive.css | 1109 +++ .../css/bootstrap-responsive.min.css | 9 + .../_static/bootstrap-2.3.2/css/bootstrap.css | 6167 +++++++++++++++ .../bootstrap-2.3.2/css/bootstrap.min.css | 9 + .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../img/glyphicons-halflings.png | Bin 0 -> 12799 bytes docs/_static/bootstrap-2.3.2/js/bootstrap.js | 2287 ++++++ .../bootstrap-2.3.2/js/bootstrap.min.js | 6 + .../bootstrap-3.4.1/css/bootstrap-theme.css | 587 ++ .../css/bootstrap-theme.css.map | 1 + .../css/bootstrap-theme.min.css | 6 + .../css/bootstrap-theme.min.css.map | 1 + .../_static/bootstrap-3.4.1/css/bootstrap.css | 6834 +++++++++++++++++ .../bootstrap-3.4.1/css/bootstrap.css.map | 1 + .../bootstrap-3.4.1/css/bootstrap.min.css | 6 + .../bootstrap-3.4.1/css/bootstrap.min.css.map | 1 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes docs/_static/bootstrap-3.4.1/js/bootstrap.js | 2580 +++++++ .../bootstrap-3.4.1/js/bootstrap.min.js | 6 + docs/_static/bootstrap-3.4.1/js/npm.js | 13 + docs/_static/bootstrap-sphinx.css | 223 + docs/_static/bootstrap-sphinx.js | 175 + .../bootswatch-2.3.2/amelia/bootstrap.min.css | 9 + .../cerulean/bootstrap.min.css | 9 + .../bootswatch-2.3.2/cosmo/bootstrap.min.css | 9 + .../bootswatch-2.3.2/cyborg/bootstrap.min.css | 9 + .../bootswatch-2.3.2/flatly/bootstrap.min.css | 9 + .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../img/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../journal/bootstrap.min.css | 9 + .../readable/bootstrap.min.css | 9 + .../simplex/bootstrap.min.css | 9 + .../bootswatch-2.3.2/slate/bootstrap.min.css | 9 + .../spacelab/bootstrap.min.css | 9 + .../bootswatch-2.3.2/spruce/bootstrap.min.css | 9 + .../superhero/bootstrap.min.css | 9 + .../bootswatch-2.3.2/united/bootstrap.min.css | 9 + .../cerulean/bootstrap.min.css | 11 + .../bootswatch-3.4.1/cosmo/bootstrap.min.css | 11 + .../bootswatch-3.4.1/cyborg/bootstrap.min.css | 11 + .../bootswatch-3.4.1/darkly/bootstrap.min.css | 11 + .../bootswatch-3.4.1/flatly/bootstrap.min.css | 11 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../journal/bootstrap.min.css | 11 + .../bootswatch-3.4.1/lumen/bootstrap.min.css | 11 + .../bootswatch-3.4.1/paper/bootstrap.min.css | 11 + .../readable/bootstrap.min.css | 11 + .../sandstone/bootstrap.min.css | 11 + .../simplex/bootstrap.min.css | 11 + .../bootswatch-3.4.1/slate/bootstrap.min.css | 11 + .../spacelab/bootstrap.min.css | 11 + .../superhero/bootstrap.min.css | 11 + .../bootswatch-3.4.1/united/bootstrap.min.css | 11 + .../bootswatch-3.4.1/yeti/bootstrap.min.css | 11 + docs/_static/custom.css | 65 + docs/_static/doctools.js | 156 + docs/_static/documentation_options.js | 13 + docs/_static/file.png | Bin 0 -> 286 bytes docs/_static/js/jquery-1.12.4.min.js | 5 + docs/_static/js/jquery-fix.js | 2 + docs/_static/language_data.js | 199 + docs/_static/minus.png | Bin 0 -> 90 bytes docs/_static/plus.png | Bin 0 -> 90 bytes docs/_static/pygments.css | 84 + docs/_static/searchtools.js | 620 ++ docs/_static/sphinx_highlight.js | 154 + docs/cli/index.html | 1026 +++ docs/cli/install.html | 1056 +++ docs/cli/simulate.html | 1152 +++ docs/cli/translate.html | 1607 ++++ docs/dragonfly_energy.cli.html | 1061 +++ docs/dragonfly_energy.cli.install.html | 1041 +++ docs/dragonfly_energy.cli.simulate.html | 1041 +++ docs/dragonfly_energy.cli.translate.html | 1324 ++++ docs/dragonfly_energy.config.html | 1202 +++ docs/dragonfly_energy.des.connector.html | 1273 +++ docs/dragonfly_energy.des.ghe.html | 2087 +++++ docs/dragonfly_energy.des.html | 1229 +++ docs/dragonfly_energy.des.junction.html | 1224 +++ docs/dragonfly_energy.des.loop.html | 1702 ++++ docs/dragonfly_energy.html | 1337 ++++ docs/dragonfly_energy.measure.html | 1392 ++++ docs/dragonfly_energy.opendss.colorobj.html | 1408 ++++ docs/dragonfly_energy.opendss.connector.html | 1317 ++++ docs/dragonfly_energy.opendss.html | 1388 ++++ docs/dragonfly_energy.opendss.junction.html | 1240 +++ docs/dragonfly_energy.opendss.lib.html | 1079 +++ ...agonfly_energy.opendss.lib.powerlines.html | 1074 +++ ...onfly_energy.opendss.lib.transformers.html | 1075 +++ docs/dragonfly_energy.opendss.lib.wires.html | 1074 +++ docs/dragonfly_energy.opendss.network.html | 1614 ++++ docs/dragonfly_energy.opendss.powerline.html | 1344 ++++ docs/dragonfly_energy.opendss.result.html | 1153 +++ docs/dragonfly_energy.opendss.road.html | 1237 +++ docs/dragonfly_energy.opendss.substation.html | 1259 +++ .../dragonfly_energy.opendss.transformer.html | 1312 ++++ ...gonfly_energy.opendss.transformerprop.html | 1304 ++++ docs/dragonfly_energy.opendss.wire.html | 1438 ++++ .../dragonfly_energy.properties.building.html | 1382 ++++ docs/dragonfly_energy.properties.context.html | 1215 +++ docs/dragonfly_energy.properties.html | 1177 +++ docs/dragonfly_energy.properties.model.html | 1408 ++++ docs/dragonfly_energy.properties.room2d.html | 1346 ++++ docs/dragonfly_energy.properties.story.html | 1248 +++ docs/dragonfly_energy.reopt.html | 1720 +++++ docs/dragonfly_energy.run.html | 1295 ++++ docs/dragonfly_energy.writer.html | 1139 +++ docs/genindex.html | 3806 +++++++++ docs/index.html | 1047 +++ docs/modules.html | 1071 +++ docs/objects.inv | Bin 0 -> 6602 bytes docs/py-modindex.html | 1177 +++ docs/search.html | 1004 +++ docs/searchindex.js | 1 + 245 files changed, 126877 insertions(+) create mode 100644 .nojekyll create mode 100644 README.md create mode 100644 docs/.buildinfo create mode 100644 docs/.doctrees/cli/index.doctree create mode 100644 docs/.doctrees/cli/install.doctree create mode 100644 docs/.doctrees/cli/simulate.doctree create mode 100644 docs/.doctrees/cli/translate.doctree create mode 100644 docs/.doctrees/dragonfly_energy.cli.doctree create mode 100644 docs/.doctrees/dragonfly_energy.cli.install.doctree create mode 100644 docs/.doctrees/dragonfly_energy.cli.simulate.doctree create mode 100644 docs/.doctrees/dragonfly_energy.cli.translate.doctree create mode 100644 docs/.doctrees/dragonfly_energy.config.doctree create mode 100644 docs/.doctrees/dragonfly_energy.des.connector.doctree create mode 100644 docs/.doctrees/dragonfly_energy.des.doctree create mode 100644 docs/.doctrees/dragonfly_energy.des.ghe.doctree create mode 100644 docs/.doctrees/dragonfly_energy.des.junction.doctree create mode 100644 docs/.doctrees/dragonfly_energy.des.loop.doctree create mode 100644 docs/.doctrees/dragonfly_energy.doctree create mode 100644 docs/.doctrees/dragonfly_energy.measure.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.colorobj.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.connector.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.junction.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.lib.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.lib.powerlines.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.lib.transformers.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.lib.wires.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.network.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.powerline.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.result.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.road.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.substation.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.transformer.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.transformerprop.doctree create mode 100644 docs/.doctrees/dragonfly_energy.opendss.wire.doctree create mode 100644 docs/.doctrees/dragonfly_energy.properties.building.doctree create mode 100644 docs/.doctrees/dragonfly_energy.properties.context.doctree create mode 100644 docs/.doctrees/dragonfly_energy.properties.doctree create mode 100644 docs/.doctrees/dragonfly_energy.properties.model.doctree create mode 100644 docs/.doctrees/dragonfly_energy.properties.room2d.doctree create mode 100644 docs/.doctrees/dragonfly_energy.properties.story.doctree create mode 100644 docs/.doctrees/dragonfly_energy.reopt.doctree create mode 100644 docs/.doctrees/dragonfly_energy.run.doctree create mode 100644 docs/.doctrees/dragonfly_energy.writer.doctree create mode 100644 docs/.doctrees/environment.pickle create mode 100644 docs/.doctrees/index.doctree create mode 100644 docs/.doctrees/modules.doctree create mode 100644 docs/.nojekyll create mode 100644 docs/README.md create mode 100644 docs/_modules/dragonfly_energy/cli/translate.html create mode 100644 docs/_modules/dragonfly_energy/config.html create mode 100644 docs/_modules/dragonfly_energy/des/connector.html create mode 100644 docs/_modules/dragonfly_energy/des/ghe.html create mode 100644 docs/_modules/dragonfly_energy/des/junction.html create mode 100644 docs/_modules/dragonfly_energy/des/loop.html create mode 100644 docs/_modules/dragonfly_energy/measure.html create mode 100644 docs/_modules/dragonfly_energy/opendss/colorobj.html create mode 100644 docs/_modules/dragonfly_energy/opendss/connector.html create mode 100644 docs/_modules/dragonfly_energy/opendss/junction.html create mode 100644 docs/_modules/dragonfly_energy/opendss/lib/powerlines.html create mode 100644 docs/_modules/dragonfly_energy/opendss/lib/transformers.html create mode 100644 docs/_modules/dragonfly_energy/opendss/lib/wires.html create mode 100644 docs/_modules/dragonfly_energy/opendss/network.html create mode 100644 docs/_modules/dragonfly_energy/opendss/powerline.html create mode 100644 docs/_modules/dragonfly_energy/opendss/result.html create mode 100644 docs/_modules/dragonfly_energy/opendss/road.html create mode 100644 docs/_modules/dragonfly_energy/opendss/substation.html create mode 100644 docs/_modules/dragonfly_energy/opendss/transformer.html create mode 100644 docs/_modules/dragonfly_energy/opendss/transformerprop.html create mode 100644 docs/_modules/dragonfly_energy/opendss/wire.html create mode 100644 docs/_modules/dragonfly_energy/properties/building.html create mode 100644 docs/_modules/dragonfly_energy/properties/context.html create mode 100644 docs/_modules/dragonfly_energy/properties/model.html create mode 100644 docs/_modules/dragonfly_energy/properties/room2d.html create mode 100644 docs/_modules/dragonfly_energy/properties/story.html create mode 100644 docs/_modules/dragonfly_energy/reopt.html create mode 100644 docs/_modules/dragonfly_energy/run.html create mode 100644 docs/_modules/dragonfly_energy/writer.html create mode 100644 docs/_modules/index.html create mode 100644 docs/_sources/cli/index.rst.txt create mode 100644 docs/_sources/cli/install.rst.txt create mode 100644 docs/_sources/cli/simulate.rst.txt create mode 100644 docs/_sources/cli/translate.rst.txt create mode 100644 docs/_sources/dragonfly_energy.cli.install.rst.txt create mode 100644 docs/_sources/dragonfly_energy.cli.rst.txt create mode 100644 docs/_sources/dragonfly_energy.cli.simulate.rst.txt create mode 100644 docs/_sources/dragonfly_energy.cli.translate.rst.txt create mode 100644 docs/_sources/dragonfly_energy.config.rst.txt create mode 100644 docs/_sources/dragonfly_energy.des.connector.rst.txt create mode 100644 docs/_sources/dragonfly_energy.des.ghe.rst.txt create mode 100644 docs/_sources/dragonfly_energy.des.junction.rst.txt create mode 100644 docs/_sources/dragonfly_energy.des.loop.rst.txt create mode 100644 docs/_sources/dragonfly_energy.des.rst.txt create mode 100644 docs/_sources/dragonfly_energy.measure.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.colorobj.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.connector.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.junction.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.lib.powerlines.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.lib.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.lib.transformers.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.lib.wires.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.network.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.powerline.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.result.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.road.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.substation.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.transformer.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.transformerprop.rst.txt create mode 100644 docs/_sources/dragonfly_energy.opendss.wire.rst.txt create mode 100644 docs/_sources/dragonfly_energy.properties.building.rst.txt create mode 100644 docs/_sources/dragonfly_energy.properties.context.rst.txt create mode 100644 docs/_sources/dragonfly_energy.properties.model.rst.txt create mode 100644 docs/_sources/dragonfly_energy.properties.room2d.rst.txt create mode 100644 docs/_sources/dragonfly_energy.properties.rst.txt create mode 100644 docs/_sources/dragonfly_energy.properties.story.rst.txt create mode 100644 docs/_sources/dragonfly_energy.reopt.rst.txt create mode 100644 docs/_sources/dragonfly_energy.rst.txt create mode 100644 docs/_sources/dragonfly_energy.run.rst.txt create mode 100644 docs/_sources/dragonfly_energy.writer.rst.txt create mode 100644 docs/_sources/index.rst.txt create mode 100644 docs/_sources/modules.rst.txt create mode 100644 docs/_static/basic.css create mode 100644 docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css create mode 100644 docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css create mode 100644 docs/_static/bootstrap-2.3.2/css/bootstrap.css create mode 100644 docs/_static/bootstrap-2.3.2/css/bootstrap.min.css create mode 100644 docs/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png create mode 100644 docs/_static/bootstrap-2.3.2/img/glyphicons-halflings.png create mode 100644 docs/_static/bootstrap-2.3.2/js/bootstrap.js create mode 100644 docs/_static/bootstrap-2.3.2/js/bootstrap.min.js create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap-theme.css create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap-theme.css.map create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap-theme.min.css create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap-theme.min.css.map create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap.css create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap.css.map create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap.min.css create mode 100644 docs/_static/bootstrap-3.4.1/css/bootstrap.min.css.map create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.eot create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.svg create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.ttf create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff create mode 100644 docs/_static/bootstrap-3.4.1/fonts/glyphicons-halflings-regular.woff2 create mode 100644 docs/_static/bootstrap-3.4.1/js/bootstrap.js create mode 100644 docs/_static/bootstrap-3.4.1/js/bootstrap.min.js create mode 100644 docs/_static/bootstrap-3.4.1/js/npm.js create mode 100644 docs/_static/bootstrap-sphinx.css create mode 100644 docs/_static/bootstrap-sphinx.js create mode 100644 docs/_static/bootswatch-2.3.2/amelia/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/cerulean/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/cosmo/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/cyborg/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/flatly/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/img/glyphicons-halflings-white.png create mode 100644 docs/_static/bootswatch-2.3.2/img/glyphicons-halflings.png create mode 100644 docs/_static/bootswatch-2.3.2/journal/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/readable/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/simplex/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/slate/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/spacelab/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/spruce/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/superhero/bootstrap.min.css create mode 100644 docs/_static/bootswatch-2.3.2/united/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/cerulean/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/cosmo/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/cyborg/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/darkly/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/flatly/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.eot create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.svg create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.ttf create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.woff create mode 100644 docs/_static/bootswatch-3.4.1/fonts/glyphicons-halflings-regular.woff2 create mode 100644 docs/_static/bootswatch-3.4.1/journal/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/lumen/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/paper/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/readable/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/sandstone/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/simplex/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/slate/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/spacelab/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/superhero/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/united/bootstrap.min.css create mode 100644 docs/_static/bootswatch-3.4.1/yeti/bootstrap.min.css create mode 100644 docs/_static/custom.css create mode 100644 docs/_static/doctools.js create mode 100644 docs/_static/documentation_options.js create mode 100644 docs/_static/file.png create mode 100644 docs/_static/js/jquery-1.12.4.min.js create mode 100644 docs/_static/js/jquery-fix.js create mode 100644 docs/_static/language_data.js create mode 100644 docs/_static/minus.png create mode 100644 docs/_static/plus.png create mode 100644 docs/_static/pygments.css create mode 100644 docs/_static/searchtools.js create mode 100644 docs/_static/sphinx_highlight.js create mode 100644 docs/cli/index.html create mode 100644 docs/cli/install.html create mode 100644 docs/cli/simulate.html create mode 100644 docs/cli/translate.html create mode 100644 docs/dragonfly_energy.cli.html create mode 100644 docs/dragonfly_energy.cli.install.html create mode 100644 docs/dragonfly_energy.cli.simulate.html create mode 100644 docs/dragonfly_energy.cli.translate.html create mode 100644 docs/dragonfly_energy.config.html create mode 100644 docs/dragonfly_energy.des.connector.html create mode 100644 docs/dragonfly_energy.des.ghe.html create mode 100644 docs/dragonfly_energy.des.html create mode 100644 docs/dragonfly_energy.des.junction.html create mode 100644 docs/dragonfly_energy.des.loop.html create mode 100644 docs/dragonfly_energy.html create mode 100644 docs/dragonfly_energy.measure.html create mode 100644 docs/dragonfly_energy.opendss.colorobj.html create mode 100644 docs/dragonfly_energy.opendss.connector.html create mode 100644 docs/dragonfly_energy.opendss.html create mode 100644 docs/dragonfly_energy.opendss.junction.html create mode 100644 docs/dragonfly_energy.opendss.lib.html create mode 100644 docs/dragonfly_energy.opendss.lib.powerlines.html create mode 100644 docs/dragonfly_energy.opendss.lib.transformers.html create mode 100644 docs/dragonfly_energy.opendss.lib.wires.html create mode 100644 docs/dragonfly_energy.opendss.network.html create mode 100644 docs/dragonfly_energy.opendss.powerline.html create mode 100644 docs/dragonfly_energy.opendss.result.html create mode 100644 docs/dragonfly_energy.opendss.road.html create mode 100644 docs/dragonfly_energy.opendss.substation.html create mode 100644 docs/dragonfly_energy.opendss.transformer.html create mode 100644 docs/dragonfly_energy.opendss.transformerprop.html create mode 100644 docs/dragonfly_energy.opendss.wire.html create mode 100644 docs/dragonfly_energy.properties.building.html create mode 100644 docs/dragonfly_energy.properties.context.html create mode 100644 docs/dragonfly_energy.properties.html create mode 100644 docs/dragonfly_energy.properties.model.html create mode 100644 docs/dragonfly_energy.properties.room2d.html create mode 100644 docs/dragonfly_energy.properties.story.html create mode 100644 docs/dragonfly_energy.reopt.html create mode 100644 docs/dragonfly_energy.run.html create mode 100644 docs/dragonfly_energy.writer.html create mode 100644 docs/genindex.html create mode 100644 docs/index.html create mode 100644 docs/modules.html create mode 100644 docs/objects.inv create mode 100644 docs/py-modindex.html create mode 100644 docs/search.html create mode 100644 docs/searchindex.js diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ + diff --git a/README.md b/README.md new file mode 100644 index 00000000..ebfb3665 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# documentation diff --git a/docs/.buildinfo b/docs/.buildinfo new file mode 100644 index 00000000..e265cd0f --- /dev/null +++ b/docs/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 8877e6347a06d7715fbcd4c727097442 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/.doctrees/cli/index.doctree b/docs/.doctrees/cli/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..80d55055c695150db02553c292681791a1ea74b7 GIT binary patch literal 3660 zcmbVPTW=dh6mFaPmN-sQXhCXIT%ke`IOc%|!~-fSLX?6Z0P$9B#=B$BD6>1uTpC*f z2_8TV8u7yL50H34>L23A@XhXey)m>PB3arwbLPyseCIop?^?fpFt}9wxjmgTo-K|^ zl4LTW+PiKdW1G^<_+R`R-}`UOj?`Rqu zF0=YLYq2)#Jn~1Z=URpvK^t4Hd;il1!w+Sweb9l*)i3EH+}+su!IyrtbAnrqX9unq z)o!va*RH&qxT}I^)KBb`xNTyL;!|r7RfuAXCpviCi3QObLVUL}l9pfH#OCY8l*Ffs z&Vr709Yf|}%daI#xEzs2ZP1bvjNInagY@mLm$;eEAOo1Uild zAM-4si({n`%E>gL^CSY*;{a<1vh%Gha{7^A~|c8>5DJrFlID99rD@GFglE7 znvyIThI|jX9`e#hnqWsMKtL>qR@33h$!1oDqY@ z5!_HkL^Ft+|K<#QdFdJMHm>@ldDZh%{4pwW&ra!c>+n81Eb`xha#4@w0oSiGTUMW} z3i&sAqp;g+nAU}T4!*kg%UV_~cmtic60Gyf|9jA(OJ)sRZ5O!e0x`L?S<`9(Izugd(Q$eyXks$BcZ9m3yK%5d^B;pVaF(vX*3P>Kl+K=DV2*xDg^x?&^)!3 z3Jn>Jg-z&;i_#GLi8=N&b={OK5}F(4A6^E1ki2L_kj-4ksXupZ#*+kecp-3P5i@4Zo6PVEi?{Ac4!x?sa=rjz(u_&YUVwHXHivV&Xvn zYv6&kS4CZ8s4066eo(**h6EpheKj1YSOvxfA6BvrLt70bfaspxFExv^x7>@X;$e_P zxsr25b;;r_Bf*7bHdh4>$+aPYm)#(?V4uuH^+f2eB;{mqT}_SQ*&L(pAk2_rcFmN` z37XX#!0bfc=16P5bg?E?7-tCkw zM7Z}93ftAvDuLB5iW!9|6L#TBDrEoM@s{)roCpgoU5 zNpVoa;LTD(1uZ1e88<9iO*-6H9jHd%#Pt=;r81GAk15i5#ceYp>SfCv&;>^p4KY@) zlv=Kp(5ao{y1^My8L|isMM(-t4<(Cf2r2l-Gvq9ySu7K1dDpXMHhOoYIlgaQ+>EGF zQbi2YL;%%*0b+}dcY9^#8&+C{74Hr=b~a3~Ki!}-x^`f7^w!0VjgxLa1OV314EYfV z$h%!ZvbiO5igYJfUqPq47ck>XLBCCaf1BxmmA{g8&Bteior#8nG;hkNKkBS2@Yarp-3>c_L;aXq` zZKoS*JPp_tl9ZhoUdX2&kilF^(7sD}z$i7i<9ZCO(}<>oiwOS_1kx?MKB(UGz^a&) zgm&(>X!ba~v|YEP67(*Rh=(l?&%ekJHK(8^ys{7A6p&@WwLlF9Y@l*??Siy?dqWIs zvwG1Ee2Ql~W?e7rm}L%E!)y2HIg8KP@8_1?3Cln5Vn4yV z>NhsCZns&)!t8F$0fpcft|}#=S66za|4m7$hp15WbSg!Si$e9q4PmX_yI`@my0tiT z?Sg%9t}@}JaedQPwS$KQm?Xwq3UI-kiKP(8IAXvc>D;g6zaSYu_|MT5c+jK2@PCd5 k5XuW{Lb)K`sl`PtcdEw>urm*3+)e`LRrC<1x}6^X1^1+rHvj+t literal 0 HcmV?d00001 diff --git a/docs/.doctrees/cli/install.doctree b/docs/.doctrees/cli/install.doctree new file mode 100644 index 0000000000000000000000000000000000000000..824c4b28bae318a7590d707b5e82f45b7fc1caaa GIT binary patch literal 7903 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 Nhr(bUF?5~1_Fvq!ZQB3< literal 0 HcmV?d00001 diff --git a/docs/.doctrees/cli/simulate.doctree b/docs/.doctrees/cli/simulate.doctree new file mode 100644 index 0000000000000000000000000000000000000000..2ee689869847716d8e251caa00df258763c17469 GIT binary patch literal 30430 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.cli.doctree b/docs/.doctrees/dragonfly_energy.cli.doctree new file mode 100644 index 0000000000000000000000000000000000000000..30e1bbd653b3d115c942ceae6b8089c7bb7a8302 GIT binary patch literal 4208 zcmc&%U29~w8MfD+v1j}-_GUK}*4|EN(>NqElZ#%I6iOkNO9qm(y=pjU&e4q2(UDFh zo%Q%4&=ykGpqpjY{)9ko0{KJzEq!#pJ?kxPp~PUA^XirKemw8ebCO7JQtMcuiK+hmF{` z|2w(~26fbT?o}1u+If{O(DTmcI^@JZnD|FjUiJ(8=9_C9AOH*@!)1$Lxabu}k;ajH#5)bS~lF z>{{vdtZ{l$`h1T-#io^Ze4T0ozn(sOkT2L#nV>epXSKi$zsMJ(uSKyVx@Y2j1@#n7O@Or3JEhe!R2AC^vNx$aTU%_c zUWcce4*1%IdmY513A~xIn`Xy8bdPFILuZaMtyY?vvf1^l0%MjuRP$b-r91$5*PX_> z4y`n58s~8>DI2IeG}Kxk5VOO1GYl+sQSpg){XYjX3yg=QR9VM;G>=#6&| zmpDc$OFN4%+({Txz`@aGsdVaJxYJNYSrouu@YLKrDJ4|ULK0nb%c6Q9zmS~gQA6ZHaE3W&-D_z$XBrc^qOdiC_+P1l0q^-%3>N^ z3ife{m;oQLN}%Q4Ah*lOuO^1$_r=}Ch-$5L#8AZo{Qxk4Z?W}mR7SpYO0PHtW7XEm z))DNV?zB9#HK5*lad%;Br#lM{pqUzm_y{=U-H9M_m1DX?xD$LoK#z29X&Nh?L};iK z{4L|q=;yAFnq0z1go7tF8d%?*lH97O6}bl-SUXAbG>aNMBC3U;;3i2#IB--*ifRa{ zZ$+7*d7`3C8qjn`H<>aNLm%61r!RNa_c`md(WL_G>cFo z7$sy}1nf9S76i73x^O>X)@J78*$iTXhGChKQ>9lZr^i9FFaVm7r76;bvB(`lK6&?} zUm~8TdKqsWA0+MZzo?H#<&uEcHPus2?XtK7Y%pUs6}W6*$pR&mgkkB>T>_A4)Kq5U zKxDv<6hqLNxsjG^BF0xt;2+@K7b@WX*rWti_EnCOHVD*P#drA`2^EuaNOPAlL%)lW zzOvX5IgvspPMa-*5cqD0B>mpbWfl4X|Ba*l^?>@lhi#;CWQNY)}rXfXrbMXuM*) KFsS5<>AwJdHfu`& literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.cli.install.doctree b/docs/.doctrees/dragonfly_energy.cli.install.doctree new file mode 100644 index 0000000000000000000000000000000000000000..5403d6de530600e7072c8ce6161c4a8bc05e9a43 GIT binary patch literal 3285 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.cli.translate.doctree b/docs/.doctrees/dragonfly_energy.cli.translate.doctree new file mode 100644 index 0000000000000000000000000000000000000000..91ac46c07b091facffc8cd0fbb472b9473461765 GIT binary patch literal 90106 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 H{l)(e*=2+q literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.config.doctree b/docs/.doctrees/dragonfly_energy.config.doctree new file mode 100644 index 0000000000000000000000000000000000000000..779cdc9d5c62529a96eadf055ecce61616b43524 GIT binary patch literal 36880 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 QV7tFSYZU?Od^0-oUj_M(IRF3v literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.des.junction.doctree b/docs/.doctrees/dragonfly_energy.des.junction.doctree new file mode 100644 index 0000000000000000000000000000000000000000..25898326724f12ce81b2d84357f6eeffe523032f GIT binary patch literal 38041 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.des.loop.doctree b/docs/.doctrees/dragonfly_energy.des.loop.doctree new file mode 100644 index 0000000000000000000000000000000000000000..a33e9dc32e4dab1d9e427754dc96b099cb0feb6c GIT binary patch literal 140663 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ʞFOC_Uq1T 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.doctree b/docs/.doctrees/dragonfly_energy.doctree new file mode 100644 index 0000000000000000000000000000000000000000..73405bb4d3e20394c7efcfa6a617e96317b81c7a GIT binary patch literal 4606 zcmcgw-D)Jq6_!?-kw$+b$-C>2e;M~6D%ttIn~K(eVwCeii#9#6QO zUZ1ASzhqNx-6rhW{5hXFV_K?f%c>vQ!qRTaV3)RZWO`oh2yK{dY5&Mt}g z!?c#+IMeXk`MD7W%K5bAM@%UQ@pmU-aq-u7kfqJX7)DAyaXOjV(roIMEcNL=?a>3; zpcC_ONFwG#nI-URcqQcJuy*#m@bx(Y;j2bk`Z>rp3WESOGB^9>A+=yT$>K4WJg^sQW+yKRC6eeGx;rSf#%UM+cjzP! z`xdhHqvc$gei`ZWE6Gw=ZrO7Bet>t(;HwE zbEY!M^VPd6TO}8%&ev8!i++%=tX_B}LyZ&yc=RjRFaJbO=@a@h{e{!7FE;7@5j~pI z2Xpe~^qY${Vsjc7C0b$R7}@#bGDc|nTuih=xQK}zV4})d1BpfH3lQPb@d8BjALej4 zMQ}BMUc+KV-eBWzUk@99ZDHd9j9D|CFbVi`Tps0vaNZ! zSUO)>q3%dq=BoJb$V_RNN&cs~P>sp5ISxH9OhWB>gY^1sOge=|nM_Z`WYxaB$D?KU zFdW$weS%t{Xie2}CY?s%STcD%s4BJ@(JLBFlK%DIC+VN)X#c<)!o#qcN{(6N$VW#D&7xu=lsfr<$Q*pu&4HguM{T^C$m~^;g3y?4#kB?oz~PQ+ zQZ|u!odwo(-(yjRHe9p1uE=znX*;6+$n>U;kT5MIhGs8dphTL*DL!_k5E`ap2F|Qm zA6iU@oC|um_Yw*_pRhZIo)9l)s;|Y#QgyyZqCuZM~MNC6)HW4zm zPt1YCaq59w#CdlZnfrx=M?9B!SD_}aB51g;+)y&Mk=c_x6;gW_50-GC>rfAvud7=^BbH1vkZnXf!1pZ>7W0zizL0?jb_1$}YaAOInQl1`5s@&c z06|@Iz%nhoMr3Y_A5`oPHA-cXySmX}u=aRf2T=pALs(2O%Zx%a19r9T! z6i2sfcIGJYwf8twVFB5`7lew9Bj-pywMS;FDixI79-L7qj=b)0=zgi@Rm9HRb${U! z<=7u;lPB)904d)EC96L#*3FTtHy|gO0*Fxr}lx973$nwKa)kAmkJkb;oJu20+u(JVtsn(yf)>&@D!RO2O~XH*NJ8` zkHRTM_yND0k#Nx8Q!zuK{We2YD+KDL{JZ${BH^=wGn*5iFnD~Vuc$XfIS(OrUuG$; zaBs+*1($6Alo^sRnE(T2UpRJ+0>orVEsPy@Bf*MdbZ@&$3&?<82dLm{SU{X>+;PW; z)}_Z|7DgUkyRPr%Rv(q`RbVxm6g_QjHhA*by%EiJ(M?dkKq6>Fh}zJeW^&5GUGP3U zf>A)0#v2%@!Arq)b91~PEnbZfehVI@xu8SCQ@6phC9n=l`DAVp+EX~E<1j2c6|{=z!7}F zgxq?kls`p!Ke9hVt%IncYvBJK6yRN4ShvXq@op{75xQHxG*J;#2hN?qb@H<5Il7XK G2mb*DwFPeg literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.measure.doctree b/docs/.doctrees/dragonfly_energy.measure.doctree new file mode 100644 index 0000000000000000000000000000000000000000..a5a0724658033100f790de062046467a8c40bf0a GIT binary patch literal 71880 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 gp#qQC>q+&R_1j4imB3ESQi_@% literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.opendss.colorobj.doctree b/docs/.doctrees/dragonfly_energy.opendss.colorobj.doctree new file mode 100644 index 0000000000000000000000000000000000000000..d627b3cd097bfe64f234f76638f1a2e80cb70d6b GIT binary patch literal 75071 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 WF9nA_&XH>123YtJX>tWOr~d~UZOO<0 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.opendss.lib.doctree b/docs/.doctrees/dragonfly_energy.opendss.lib.doctree new file mode 100644 index 0000000000000000000000000000000000000000..ee8769e8c32b143196b5ab3ccc21b78846441f71 GIT binary patch literal 4251 zcmd5|53 z{bkHlO2;~v@OONv^kUouVOYlC6#^BTwe%G}kF>VWGUHm`5|3mygf|KkQg>%DFoxKkeIxwLJ zn5Z;UxlCH=E|I{t5E&I)P1{hYzP;`ucGul&!t@INksf4N^CBr16Zh~Y`&C~r(~JX%rgIY z7qB8(Q857FT&StPa$Uxg1O;~Gj;bRX!M@DXDb+ObkGEXEs3)VOSV6asI$g&gWablg zR%B!k3H^98jc!mSVR)%YmQn4=W@dkleXYy_3A90i>zg%{NR5jPX$vL&bqO>mxdEty zPYaZu$4Xi_)u8ny`5LnJ$3gas7Gwv2?3U|rnb76SczqovuR+f3W`t|+?w95DtMi*c z;@!KY+VDm#)}2^SLMH!#=v4;0um2|ksd=`lopD98W6VD1PtMzwbWUV)UewB{W}+XnWu5ka z{r742sD~F|sO>tMZ9reJ=WbACr9mBSfL(oB1Cq2ka1-4CRI60(H(9O-epp3+i0BXN zCbur4wf-xZu4#%d8L-nrH2T2nS-a_b?0xrUkrY7!1x1-wbFf$0_c~TtB1)bK6bPMy zcJctoZFd~!I&{^j>7j?Ur0k_`-%x9TB#afO&73gPMMWpxb^lC64q|KujjqaVmRmnz zgNf_SLoXy&X%KWT!QIA^G{fRRD`jCScy;OB_Sn0F(u4^2E}+n_mbn&K9f9Ve(3itk zn9>Oxx$^Gz497@iY3t)NcNFFqaBQ>;jPIYh<4_G*gl-n5B7+0(mJ%vxA&D-zWl=pF z;J#`@H7rcrp{AMAHWKtHML2J{J|m)8cHAjlqWIvQ%}uS;ah-%t^Es|Nz9d>AiqO!M zq>%KGvX};!f_+>fX240T5@>nX%k6CV%c0@;eee3mh-$5L#87$yd=D7Fx7d0&C?nrG zrBj^Z-Py*MjU(8<-En#7+JJiNz3U$~cDj?`06=9J;v?XYcSnNAd5(b(;ZCr=g&yeM z&@@&$iO?`H7~-1H<0r0*8lAyMgo7tF8d%pIliaFkEpoRwuy&N>X%;njL{tj_M|07V zh;ZPbkTevv7G;L!iHeqKK+_3bX39_y=6YuVk=RC0x#1;V2T{TenTp^@W#wL7C#bnY zIAc&5MbY8Vqe?BRCk6Lb_=QUh)kR@a8BR-(?*nvswF5FL;wVC;7JcihS_$^a%r1Tu+bSG#Q20$~iG(~zW z(yxuOQi3Y`B1cIZ1nP}qT`nV`Vp0xa z?kr~LS25C878{~mgb=$Id4?;(o2D47Dh|LD1__rlV4xy}+kqu8|7@u7G+ z_XYcbea|FYujz0QL$c>h&#Rj$hA@LB?4O~@{Pq6!))rn&|33pydveI#Q5&a4I+^GAj=pp zHB|*sNe&7<=!Wi`~~v;mHz_@AHyCf1dm?>td|!yoOw-r(1;7T9#k(Gl*c?E QwVwo9uNW{4F8OryA3mLaA^-pY literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.opendss.lib.powerlines.doctree b/docs/.doctrees/dragonfly_energy.opendss.lib.powerlines.doctree new file mode 100644 index 0000000000000000000000000000000000000000..5cb2ad73f555be889074be415aa784308fc15ce1 GIT binary patch literal 6681 zcmdT}TW=gm6}IEd*yGDMb}m{r@iHs4WGr@OR)Plz5t|hcJS12MA)c}{HQhB+ZTF4t zYF`9FVWmZ}R1b(0hzGAKfB^_}lr z^1St%?wd>IkJ`=>;YX)K=6O-<@l2~VFLv{gM^eAk`@hi7bYFE+c9O+;>T<1?FvAso z;H5m$A8OU5>Cz9fVX=NSIN*!(24I>#6tVE=H*G<7&G@M zjV zESq=>Faa(*Koy&&ED;Uus&72;$0s?7klDcz{_%}ct|(2d{7$n!u7LgX=hL+3|Ac($sLm1 z8J{`62Tb`BpQru(Uf+)j1FvPj98LRLJ-Q-}EQ`G2VEsyfS@pn5u7eQW#xs^YwglG0 zh?DuSWSOV4gtk!1#y~CmzIot2PTMql5)l(Sl;kT~s()26ORQXdK@E+g#n9-h4M;jj zz?O6~wM7>-v}f9UhA29xVelYJ82O4dEXjC!%rzm(2a#kx|>|o2wH~6K0k30Y-zP!emX32 zMVvNt`#Oi*K|mo{I^|NU_Z;h2F9rh(yc|LmEcZPvK2mLb!Q*Ll|B5tYjQLNsjFv8W zt=y-K!Uu#%czUhY3A^$55K*C?rHXbD(Ovyy)iSgL+E#0mJO~V~Aj7&NW7ol3$V`jB zh>w1$5z5c{zb`hDdHaB`SO0&EjK}(0 z@mL+TjyNLltP$4CRu~cT4l{hgyeK6pR?bt@`u9q<1f(eCxTBg~wVwZbbv^$FSN;T8 zdl$sK1dLUOk7Mub!sQwOd(r@K4V&Iz(EFe#K`DqHO}sjZ(>Z8Sz)A2k8 zZs5Ziu)x9UIGQ#tu!w>SMZAun4{t3mEnQhHhr2ZU?qL`IKq+@rtM`xRFMGODu^DM@ zhdE#UG=eYQvB6$*nGX^A`?%ePx!qzHf_aA>BZ&AUA78%Tzk!2)UFK%!(0`Wr7JC;M z_7!*hE2bOndiC_ax|W_)yS(=&apHjBZsy@MGApJvsh?I*gudEu5-Kv03)m zYK2-W^oC;2PF0nfr)wU%?>&|P2!bzL1if~A6Tg^9iX_;NL+M64h+u~4> zVRr4l^&QI9_htv?7ONX11F)9~s36Lm4HA<)@8Yjk=B=8>KY#>N2&QrvR2G!>ZLCWOgAD#q@x z=~gk#nfQUJZmB!;g+q|I8rwwDi`_gt`3B0Mcq-d`ysUP}-hiBF3Lpl4=u7?G8~0T= z;fVt);jmKIC~T8@#te5S(@<{+DU*o4uguxrb1lMz&X$pyM8nQ1`1x-C8Egk@!T{&BK8&-YE*#z-lnDoOZ5Ocyvq!V6|r1 z1m+7Q!sYp}4e8hn%oKlja48^5q8JWF_o&?aOsn0QUJ5czH+Gv;4a&f%nvChI)M>vD z9hmsxQ~Z^w4s{!kh)HJPJQHuDR%^!L5+5R#Y!~TZ$?IjNQYU5)O=8xJ{!s|d;1Kl- z3Sa(=vycgVPRpw^mB^=p=W447R-?Wx*9YWD|4^yzAx`I8*m8=2DoRjhl&?F9`|0F#f0{{uwa B71IC! literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.opendss.lib.transformers.doctree b/docs/.doctrees/dragonfly_energy.opendss.lib.transformers.doctree new file mode 100644 index 0000000000000000000000000000000000000000..7bfced42c16d4b8f19737a68d42987b9b00577b1 GIT binary patch literal 6829 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.opendss.network.doctree b/docs/.doctrees/dragonfly_energy.opendss.network.doctree new file mode 100644 index 0000000000000000000000000000000000000000..122a30c18ee76cdb75326d0b1abe57f82436c2e9 GIT binary patch literal 115149 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.opendss.powerline.doctree b/docs/.doctrees/dragonfly_energy.opendss.powerline.doctree new file mode 100644 index 0000000000000000000000000000000000000000..05b368fcbf178457ba87f09b678217f468220995 GIT binary patch literal 56362 zcmeHw3y>XWb*3b1Ml*Nxu!JpaWZ5k_Fe5S=Nw)kzeoB7GU^5n$u?^T(o+39!tRn*km_bun8&H z-E3t^?RWln_wDZc7>zv2Lg7*0zyHTM=RfCs|9}2RKQ;0TSAAn0`(LsxYPnwX%#2;H zH-owpb&|1qP-`za&A9VSXWvhCp6pB|z3ff`K=_Korqvm>zdgwGek9Cr*ls)zu z(Tpg+DROGD7c^CIcf=iaH$B#wa>tXA*ozyE@hW+9J+v2s=6qxM(W=vQ!iD9Tpyf2{ zQ8d#EPCH@4YdY3aP;a9c)q+YkKIohw>Ws4MdY1iQhx0PpvO#&=aknSqRmG}%Q8Fqx zoJ}@To1NMAoSjtcI1atJb_~goBrfvm5plh#*07@piFh7q+DrUttln6}ZN%epmEI9|lb`zW*I30wG2b4JWb7|xx1hq(~7BW5) zM&R!}$sl^$aq{0rVxBM;USx5Jd{m{YY+d3C6(H}5&&v~}7GooL!} z9dE&n@en!TVZ3&A?{2@ zSc#6-hDB2w(6Hj4S7gX2S#L=l!;`L|ZPt+1r)2%+?A25|7z=ZNn|TKU=Ew_6XmdxBtNT!6Dd)cO>Yn(y z;+~jFCZN;%AxuV3vW3WFy1;%rW+%BHaX(7J{uwQ7Hz6;;7#nAdWw{zxwjpUZQZ$91 zDx+|WDCFdgQ6t5aJ(o+_4n`Td%q1r#BnKcFf`53Gj8@o|G#%Bx*>**@&E>O>_W(JX zYF3tAnRg~;l9uL6#nMdHH@hwGOAy-^G0Z5mJlXTVfs9{3Z~rUl>yr`Y?kin>fvEf1aMW!Q&NoY6I(=uNerp=PKQN8o8;-^a0~fM%cE8)1q|y|< z{@D6;>jov+--trPQ9a55EK6`Id1oSjYBH^1$h=}`GB0Li8u-cxo^rLSP8c~jHxRLz zrfI)%7}^gr+5w>3nHM6v#!xV{;~+F0!TMWd<9O0d-c#CSvOefCX8&#~vdb6kjwhpD zlg%RxkGGLV8nQk9LpS-Z@+JWg^LD!tS5MiEwv%o?d0o_QwSq9NMoV@WKi&>#zH%0r z;XiCrRSfaPj^>iQaZy)qZp-A7Om?Mfexp);^Zk(@piq0xKaPKt(<|u0pDL~2KZ(~_ zmnZvBwDO4AN@?HyTzOmdY+JoMjFZrJhm~hcE?W!e01L2T=%06?v#LYMA7);T`CHA3=*T zeys(~*bL3cS>KdU=q^RZs1#)cGH6)gdSMq$%fW4%{`X) z^Z8P$cc`ELGgY(8|2qCD16HL#{=Y^}1hz<>mTa%t@xMz6n~)GMx1i`^Vn(n(@0@8h zyqX7NVHr-_VH1zzkgre+)|*5g7dUCEsqK<$BJ@v)(A~+Joh(6!qzYy8K~hpgBK&n5 zzzPdS_^%RITvfFqUiW~*CX3BDvSQbr|)f=EZB&Ku4Gfnvc+2>R!O`f?YQcs(%(uj$13{81QroS>@;PqWlrTwwvDLZHEPnq;f7>Z@qKIdV4#HE%LSS3|7!=ELUnS1XP1-BUQFz z3qfSduGO4YY|k}P`fEMtdJ*buG^{ztYDZ4piUT=cTxN#Aogm7GLBvf19tOiVWLfeNaB!UY&){1>Y;6^@P608mh}aM{$hyWxD` za!xr-&uP}2=?cOe~`{&}G)(wmGb{;a8rYd}hx_bjo!Rp~qDR+awH2rLVI z3R>h~>;}A2>?~j&Do0QpXvlpDrKw@W<-s-C4UD$QK~?m`b;f$@yv5g#y%=7NjrqOi zyc32fF&_p?%%h2#XfVd76Cy!q7dgoYlNBmc$IQlS)?!|mbkoKlz;(hIYwAuO0zSf8 z%-6$I2wgfygL`8Ru;Ze%3iYLtTTv)~4nS`*8u>Cb^6!J3wI*ko?5)WYOkm}*?SCrp z$N>aeGO_loLJI{}`pow=SYls8ff}<(D*zd~2JnBp4Sa_F0@uZM7Ax`)LuOka@CcBH zUVBl6xk;;LH)*b$*88X(vSBHC(>S!75o%kaF)xj5qxM|HH&R3u?5?t4JotY^Lkka^ zsc71a$SI9J_{hMrxkrY1gow^!#J~q8hAE1vP=999wJsq{r7K-`{Y@GDF7Hw?-o1hK ze%=I#-lWat5n66DE#}7^nelhJGqTd_ZHI?hPn36B$_`7b^sgiQ-Q{1?2TmR2St$tC zBdY4};#n{2qt=}~s|*XeyTx9raoVah?={)@IX{Ai0NN#)JlR-U@{toNSbL=MW=luX z@BqC9l=97T!xd7DDG7dYtdkFXO&Gs2UJNNzk$TO3V7FzZB33Q1?-SuS zGvJp@7(~jjWhzZ8%m*^&R;~z7QSROTr6l7k@4XBi{STS?Q0P)i&WOD6kd1#m3Z$br zQ>n;KcYsa>dHhdMn|zfdKW6vrAS|!|y`cYc(Eo8pe>vAo{T0_#>K9n4Gz*)}?&nh1 zOnhE5k1eT zNZ5E!nHOQ>&-dX^K1L2JRf>-ziW??V{s*a2H2OH*M_cW#QgUpF`T9_Y1l)Hgw?7!1 zWCtat_E}TCx7_HB*R&Gh26Y@0xNeYQGqSz(c>%S*06Qn1U4z@q4YJuuk!ofT=+w!~ zXZNc4zXAsMb~XPcFyQ|d{-pZX{~e_CwL{H+89Ch-{NJT|zJ_}J-=n8*;3+ZA2_#zU zKHTwNq1r1_G0_Vkn>MQ{$wJ=$jD*bg0r~#{*)u{`V~ymh`%gLH=@2_OteM%n9<*ew z!fo&nJHjSC^J#1NGtso1375`w*a+*NQVG6)>D!9#(qjJagDHbeFwZN&@vyW{pW-{# zM!6fz?k1Fb&i)q7CY!K^&-R@8|CfHUqZa1xX0V?h-ox&*W*{H8%4D1q#Bv<=qiq&1 zj#1o)nGA}{PJ4F5`*quV4_bR&Zts3Xfm!|%3+w1qAkc8;l`V9LFIUIg({n@d7-WZ zP&A+Z46*!L0Ltq$py-Y*L=;VN7ozM02djZ7ccEU6C~wD83Q-KjlaMl@m@qI!3K!1y za*}f&nDU0>*tlS0Ev?12N74F(ToaILUzSDN!8=8R`F4=m$HkE3GAhB5KdWXUve18>=?+PyYHpn<6Q3icf<5)j-8RMZFvq{~MmtsHiDcsHl<*RFrCkPI^D;C`3i`IMDPRp+h@A zZARLYb*IIITN;H#OQV`*ouQX ze1iw}KILeO*hWs(T%R5hO3!u&`gJ0@ru`S^5poC>UoU)2-0a9P39b(~ni##?m*9dBh z#@h8G9$fhol}U;LOyUj`d5!8l z_UXmyp=*#(JvcdSSy#)GHM(?Vl2!sDRPvrDo_vhuv2pYZ$84Z%^a`8Z<*tS7X$GNq zwEeg;DK^woMTf5E74amw;h0rcyf?lwsdpz(B?oyOnY}h=P#fC_O^iMHDW)Pn7CMA={)Enr8J780m|N82#todG z3+S%1v&mS)ZZ5QO8xR7vtz|4|G;!gXi+hEz<=Bm@2n*A-U}Sg4$r0`Le?&NO<-H>* z$SCy}GNdT+Tv}|pP+2&UPXZkfz$bz8^t1tl`0Qx~lRz;~8g}vMgc`zB?YYpaFF5s; z&IE58C<55s{tBjq`;=dt>8_W}4aL<{=W&Yoe$qN)S3&P7;)gROG8mOVMWklRFiK7y zXo~oRY9RS1Ycaao-FMw{#T|K>_@puKl^!WPtC$~r_NWEtf0C-n&K@UdT?$PVkxNwv&esrLS-WmsR%TS{8g6MpwZlMrHM3CyRR(rUm1qXmj@;@?QP8= z9kG<2?B;gVd7kWEQRa+_R~I$uU9;X(klAX?dcTi)`Kv9Icc_|icHDJR4`s8HF2xaUUQ zH8*cQIFKB~ym=ah^5@O;CN*$ajd^pnkzyyyjbN9*j}csIEb`p^n^@M=*5s~EdpDbN zc11hbF)TebWw(*=oOWa_I?Mcs$_X~!XB+R-DSN!<2Lp2hA3dP#T^X5|vnjgpos7-A z10?h&(}nLyg+9&+n|f@MZLfE4KEP-%XHy)x;JsN|r95(Rbsx2g*b4c9vT-X-+(c|; zTOYNG*ot(0a;E0r179eYX3qD#esVH5m||+Tj7D%3|8X#7STGzC_^tQtr@zh(m~McvpPW7%D*WSsFMd0P+ts=G~U7wsyreizr=Nn~a@jVml`N-^s zx%S%Y`EHoEvyYbb+7Gk$KDzf<-ln$~TSzLF_}>%ii4yiw+y?LW-hYop+ion`(BA2E zKDOJ0G9JyoIb%&N?ZcacGY2ze#MT-9`p`jD;gdSwN~t+kOwF|i59@XquZ8q5${y3( zXMWrjLny{M?g|wL`Z^5k+{A(2iJC+lNSb0VBmaGVBu@@DrRApmP476+5707?1O1Sm zSR9Bwy>@Y+n`xuoz&mF6IRYHKJ~U9EhiwW>eWcAebj>F!Zpnd(i*-DQQ!TbA=neQA zc?*0S1^=Ok*IUNZfR_fA@@@Cys%-MH^As4tMlff2&T(d{#1!2CKBFF}*X%}gD@&1a z4}Az=pySJ$HGdaz$s!Y4v;B=oT!r~!vNheC9X@xQMr*0LBkx5yMI0p&7&AdhF=iB_ zqKk58f`tdU3BrYS%L<0I?pr|sx9;2MiCH&$dhM+Hwm29ro~sP}@IVGGnp;84c8}Hy zNxR(Fcgx*Sc}MPi(?-8ZwaV>Y{nn=ch|mq$wS$=cgQ{%u$@66T!^u1wQrwyr91nNu zLqU13&5vh|$>K6jsuQ$e10|fikZ3`iaS?_3{J_$arS+G7U`e!+`oPi%Qz6Na_@%k| zXnAWxd}4_cp}lGL6Sy+?PMg^lm{`)PSsts@s_D-Y=}ZI8bF6ZEm%$cq4b${?MJ4YC z{i}d7{)?!WBg=2%DTOS`Pe^bXmmWu7J0Zo2?s*4Exaf$m8EL$n&Il{17{Nt#@~I?; zR>m)j_VRs}sTe%^v3u>iCrI%nEyY!h`~C4C(vxw&uTi10xSw(B)T`1x($=42LC|mz zNXCV+>}v|AUEEBB`=05hdHOn+p#(UC64mgzZ+2xZ?s*p9X^GsR-Kf(Ix1ob?5YsjF zQylLsT#)P2w_;GgY7;k`M7UbontCv7JNu?9r(LhcuYI}v$dKlr zGg%d*0u5kAxQf)b*GyJyMfz$VwTf_+v{>nfN=cSuY3VHU3-z8UUtN)7>7Sq{HkM{j zuiaSsB+#K~A#V5y^gV-)^@>O+9CIh1Tce}aVorKpNn@;!mUc>4d|+2eb~!36&7&>( zR_LYasnQl&9!)r+%3g?_vy!WAH0S<(B!t&u#QH`xHk&C^hr+dW%|q8H_Aq!_jZth3 z_3}~dBA!yC*iv-?*INB+DrLA*_YDQjVUFd5j0&LDd~ol|FY<+p<~3d0;wlj68sy_>=VMd7c%k_ z)PD#9xXu3&Ju#bSPb;u_VIsqxpuX#&qxZe_&gzMKj-I^hu0Go4jQp zvo{-Ef${IuSe~vChCXH7%(S`dEw)6Y6SXt=E1@N_lhcS$?hL-G$|ldBCugt%xpUW` z?-{eEaL2^7HF=Ew+(Cb4>CeeS?C&*`GWg!}maq*IeE5(rLiefMTf+VhvO`#49ep_@ zs#Wo|zG|zD&s4S9jWNb;BFXw&i7MvN<8mcB@r`|T4Tjr;9)&=d39?CG`h+jpAZNEy&? zi?5_F5A3$hHVfVM+Vp&B(tCv%424b?WWb_5=5_jJMk&-mu4NpPg$ysY2n{nWzxRb3 zQKm#1unN2qHB%NXG~LRAYT$zC+sw6$>8}KdV0JoD``xD%t9)FQmSs8kYccsBrfRa@ z*GA$hd*76@a_{>rT1|W3R3_#}-N&C6JV`)E_pyns zBoN%3;Mb@Gx)TEVloE)+{2_dzlRj$*=BL?L3&ACpeXyK^?;PR-pyCt9dNoF^1rAYC zGxFlFj9iprBn^le{$Atw zMmeTjM^6k>*wacdMbR@frX15~KRm45Fi>(Hta%D;rm)78goK-)MkWb2l5)V!J;X%Obj+BL95LaB-x!>klC_)O<84P? z)2;=t;AJIM=+1ju5ZwP<>o}F*aPmRLZN_pkXFA0WekmNl39n=*IC&0@ayWUOo*104 zrTUabY~W;{G1-8c{;8BG?W(Q|7NjZ&2NLL%eCi>Y#} zk3w&Rh7Gm?wLeoLV;K1;M9uVzLVHvL$pz4}83amw>RzBvDos14V~Wqgkw?qOKT6eP zk!KeYR|9zp6qTdSLufRGIw{5_;=BvFB;rWgfjCzZ8+{}e%`Dmv9b}LYA}I!hoF(G>fRG#0 z5Te#+dVFk4&r*i3KzGo}pm^moql7YxI;;JrkX;X^GKfF<`98!E1{0UZ`P=_EP0mA3FY4 zD7dta-q3N;R&M;VM8+`kp@W*~7drm8B57?-OHw_=T)43*ej@c2{Ra?9rD?}>S*ak) z*ZQ@L{MS=8StR*u$Z$1~q(D(QoJ@m~6r7|OmzZ(@xg@4Y+JPxQ6usVS&41R!l;S1- zN92bfWq-)+VstBC&bt4(u2y&R;nHr-Tl@b3iGt(LAyK%`wSOr@;1924DEzq>jdJ|C zkDeI*u&0&akD_O2{5eKlx6-KCU~B)n#bWeXlWW8#;l04eSXMQQtv>e5XDp*P_B1mk z`obP+reExtQw^-mwSTjNve3gmdBp8Qp5!r;v`6}B#pK{q7%d?G15`~GcpgRKY5-5Z zl5*VnMYNg19g}SdJD)%%2|JQGsqprb4=lpcGUVc#luocvx zyY4wbZo%LyXEO6%D#5|zS;cF{Zqmi%WJZbxV8SaI3QT?-jdC#g4SHf=!k$(FCW@Y+ z!Q^&kNnU*gGnwlKT40gw6$8n$YccMn$?gRs#+h+lX!Swlt3s)zMf3)d|CA|_F^2pJ z3^mg)h`g#ANY;9vW};tXsh-2sMJH$<^p}dg!Qn%T#{VBwO%^_W7m2F@A9>2j!DGX= z40vdkC3K7+i-ZnIHK5}aA%|WwmO~6Wuo{B<#>91Dmfjjx1{p(?)ZJ78)#id@M$OYc zpT)htB6kOl_amOa5+mGIOm9EOhAO)YB{iU@E5`C9K?2`bMLyOBJ((P{A^Qu>yxdu zb{IO%xGL(JO*YFEVy!cqjN$Nbj6>5=C)r*PYVFu-MD+bPY-VZJajEh{cBAb?>Kc?} z6o;r=?YJ}RZktWU7l?m54nov4j(gT{oZ4P$;m1T61Tjc;=DjnWWc`6oGQmlxqTNMg zsED8Kuz_D&;-FTYvulg=7Nm@T=5V=_?3hP2bh)kZ^66wtgb#>fdrkEW_S!6Uo=&#X zDT5XwJ4;I_7@@*lJO#HsvXm+v|E@As12bq(6d>JW37bQw6@+oM;hb_H&J9V$wHxZ^ zNV45I<3WnC9k(NyX(Sn`J9F&?)VKAt9X26FLgnlc5|VPy|j>c9ltj?%}(;V(5VGsy;^t3 zfY1ys1BM(%Ye91!Y(gSlT`Gh-nryY(xE@d^B^x}b+m?EJsZ~`f3Bj@iiYbLnT*QxR zwy_kZ?9}@@sTDcxdQd&HL<)7WbEXyGyRv3UrX{twddiDDuCm+koq~uyasfsJm7Aog z!0a}InFz+gZvukWh-}q)uL0)Z33k#G8i|~c*{0K^+Un@?iO@ccuHrxMU7u_xdxPdQ z7odm@Z^?^0Z@+jl+1heiRal7wE3I)&q!ji|Tr!R1GB=J}(UAiOkQ~jl*r(fPf^Y#A zbt&a!1R!TMc9zgRF}h<6>HFV!@G#`LHJqqkvD>+KEZGg6T&gPLR18$37HP=YXrs>Z;&z*AxbZ{TWDe{sEfTA^5<^gEVL)6 zdChs~fba`D$WcV?xlA^1iFCIS*xVR5GM5CES(HZH9p*J9OKvb{#t zuGh)$GOD*z&E$!j>6#O%8> zK7E|Vr*8xJ^z8tj?pO8c{#ADGpih?*`gElgyZ6ec>s5TZgT<%g<361+_vw6}Plo_~ zI(OmI;S8Vl!TNjX4{c)dX{VDU|pdx05ZVsj<%A zQuAQ2q&-jwo0Bg4fBbO0wQIwkx1*a5fvZyW1q%#E!D7l?a>8&U?wyY}?>)cgMz|~O^UR(5an8BtoZtOCPgj1YadCwIW3xfqwA}4wz1eiVrV+$! zqUklFmf?o+bMeVvj(;&;WL00k9(a-8Fk&`>91YWQn!e%2PsMD8vWJ!vEGOm11EUdI zo~w$R6?4oSe=1%ytE>`Qp<`q|u@g;S-}KxKXXlD$xQ4&Ev+T7Ew;2S>z7a%DSZjIB z2xX`W)NtsMu}!393Xb$H_<>k(G1k^Wa~PX*tg0y{&4X+#;cbl_axB+~*P^=4CiO7% zt$GwfCM1J{Rx==e#~Y3w1W3el#noHlX`&gm)0ev5*z%1H$`i5iP~W6au{mqbo73iT z^PsuFuB@0|%UJOv7d)?A_x!CDC5R;H+{Wr zW~9g7{TNrq+J@)XkRhN-*P*WGE?%sO27_AY)tY*!*BYMV2vZ1_h4vmBzI>v@kk%QY zL2H~)y=zaBa33@m%+t_?Q7L3_wk&K~8fDk=c}*B2PGN-XzJ%K+gl#TzYp7XnKe?Wa zSwF2<&Q%?k>WJVPihT&as*&j#>0(CUknlwdEEruF`8i*6N3Mm%4a+gKwjP?nN!~w; zsCSl^)?L>N^@0~;Kk;*?-WtODtkzC&wojbCw{}XlrUh-iVXW3vmfDHar(smw@f~9o zULsDraVy)6XjqXgD$20NMr%@i@RZgNWoyVQ0vo*^>sh-dZ3v(RTT$KU-sRQpmb1$F zfRk@SpAG+-5mQ+UWsSsjJ-ZLgw5Ti4aqjP?MfU;B$m2=?Gb^m0eku#?pE2!$-|F52 zi);!ixC9|`O4wl{jOze@H?o~${<`@aB;?;rg={i1Th3CIvsC2ga88w_eiTwuNFp#k{8ePEQByz$l1a*UY{?nau zWw#_FGdP^(YnE}nf#F%qX62)%yA9LxGotGU?Ntm(Lfzjq!k8^;0;xNP69xRlAP2>) zW^BI1#_$9zjoDrO@SS-2X3CTB+8M`lMW=xW236?Pm`#%Yd376L8RraxjR`7u(V}#) z<`|pUh#ZG&3TU3xLa#wG4};iz!+hyiV+{T%Dak;THUN{{-azqHQk0A}Z#&F-{qGEZCgxWU|}SR5cBkkFl{tuF4ebBZYSJI*vgfZ=4-y?+^&=ED7Ms^$Ub% z&rmh<_9XuFQh%j1=D%VZLHg6uEjPC3QI3rxA>3(0trK`;Q%Etk+m6++U>ZEbb=`OI zScPyCZ7|;;!i1qtvq{gVY~ljj7tbn|R=JpIwez_iw+M zvJ%RgsKQw~#A$qqz&T*3qVl`!GSOj0V(CkBzH{W#^Gw;!WF z3+BC0CMX`fM?!zyYwmPVnelMzDTLRSmTG5e1YI5bv(VJT+I7P> zYMV5f)kC9MtMACEk{E2!aC;{4UK%E7p1YZ$AqV7A5-AxON4hnTBrG8b1Aia^49sia zdiuG{u-c|CSw%&jGka$^?YLt78CWb##)bLM+jUNB-cM)8kL2sF3bv?&`*;-lg2?*t zE^2)*&nooYTu3HgRhlGiSgu9$qpqrdYax#Ym}+JF_sPe7uWk4t78_P4-^TSuOvdO% zZ-kz&(KH%wz~H86EJ8gq?KWg3@K2Lw{yikFyy@*F)W2q!E{3{OZcP4O;ed}7M+pu@C~X# z@Q}-v_Rrr_j$xP>2RUEo<&4$lrZr z7j1p0SV|40hFX?1pJZn)c^CQG?&8VXVxMVge$l9g#R}7FVqx-K1C?8rEf!WN`JfQf zjSug;<*^LKd~sWo9$1b>n=*mjo?BK@1sCN4>5D4oL@Ea1rqhJfYMMQ*X3_j3^X1&c zQm(3Coyoqc%Ivv;xo%CH1RMGe@a%KPUvnr7xo{> z733g1sVyAp3+YGe$Q6fXuD&>!hVB_%*&?x@-=o)_{efKFnjVv+Le=KN;q+z zodM*1RCdimB0V-1?NqPqZ&3xj>(Zk3Un6nP0K5=udy?EgV z2lK)mZ4c{-@5+1Pl6ni?c&nLWw;5ba6t|OmP<4&8fVu8u-!ZW4@%5&apbyg_E6$j`Y;|{3!Y<=(|;+%LtWYUsAClbU&Mc})!cZwI*oW$vISjxzjdSd>ZFp>xo~ z4*ws@?~3gKXig0VH2HSB;LMBr4`+&W_k)?^d6+2{fAdl1CksZ>A7$<@lqlFo`I-YY zvs;u|Q4O#kg&r<|OmTZS!I)xl>ZTr7><$hwsi^FAs-_4rCy}^!i0PxGH|-{x=|Gqw z#~ffbky8SUq!=FbULw99z&t1bCXCvSL5G%eehz-w6ic+zz%G&!nRZaWGyCz}+) z?75z_@0^70-9yaVsf2(SOEFzAp#m}y#7F@FVnhu?LCpKnqJWrRp(hS8{Ap;2QN#=l zG3PR;NA`d(KRp<}WE$-PE+5-};F2S{AF|{x$t>r}zWK27e4^XZF#5yFCkiDBHc<{M z)XZ*S<-@80w(tA4fGN47Q@xK016Ws5KMkJm8FRC^@IayI0Z8(Km$!$K1d}5 zqI^xU-@6zgiWHTqVJJlTHd+*j@*R5Oh{B(SMijx$UM4MP)5DT`0F?U%1Qc}%u?wDj zbRXhLhUR{7QaDkRia1&1e^Zyjsuf|@(kS|)$y}jC!5+%dgqqncnp9K+Y`^zx0Zckh z9Cx{FXWye(92`ng@z{4$HAN`-UwDhXLrD*%ylJnZ-3}zlGS7kJ0pyZEA}NJ;Jdp5S zvJ0H9c%3K!2^mGnEebX9*meFC4&IZ{AvM3C$0cwuN+kpwJgAuHU5wyBG7LBnH4Fs@ zKZ_Ox96U)+91i%?&~TuL8G3?oK6@N`4}h>b7$9U@?E(qU?>|V$Q{4{~ek{Lwl`s6} zPcp(pzol{XhlO7#lqlFmIV?~!yM=|eYJlzk-Yoz_{yso5&B!OFj_Fy&=-}Xx3d#O$ zs-_4IHWK#^4n39grv3Y9qyrxE+;V{U1LTtcA*qGGY!Tu8W*YbR-Vz~uNoO5h_Cxkm zN7`R6C-h2NDQJEPkT_IA0LdRJW_uSSAd!Lrkcb+F0+QF!q5zV=q$ds}{Ap+)=|W6) ztCPAJEQrhFQc(Hh7RmYCF|>r;V~Vx3 zB!bs0B{!@M85by1qCDo0jLxLX2tp(a++IPDBPe-t*A%gcy7#{dzhvIaZVi3i4IF+> zQp48vCdd-umntCwvN-XD5jH9F;1nlru~K`ZY^D+U6x>Nup`4~=iU{e%CX(aEh;TKh zLRM|y(kZU@H*wDc|!# zkctbD+qj6c5+m*hkCcV`eC`%9OeU|9@8In)g&v^rQ1lg~RK%fZc60;PAm)sb`S=Vw zOrf-}AF6F5-cT!khRskMqqf%YS}ha|P~p5tF&u-ZXtav0@hkga2JIyUl9*L%Y}z;4 zo{!sx#x(=tJisPR-BGU*bB#?pODJj}!K{7233ecbUhb+_plh%z-sq#^Qc3?zJPeZI8+gw3BJD+s!a+2dgV9NDdIS z3wN{JWzXM)Mcqa@IRVJ2;TkczCq(y5AbsiXcl;FOIpc3M3e{6eTKzq;dO9;eD!XO) z%a##t@HXHOR?M*Fps{MG*I`A?(2Orkum$L3OH; z9&+d=JDUz#h&rPEd<3fwAgEjTyLi~L1ux%dww7K=b+bcskIpCmNX~@fgF2l}(w~Fgd?0=T-UIQ0;D?}w0Srbo js2p!Dc}gX7ou9JYh7&c(#x^M+%|`y8;Dsvc6J@&fK9umyJo6td%Bvc z>fN14U=s}9h35dGK_mg0h)9W)0K!oqMEt@(2oez?5=9Y-P!a_x^7-}x)s`2X16r0EBZOY?56)`)6e(q^NzsM=cb z8fp8z?W1pLzo|XL#$xwk61C#0*Jj(0qv{9sTI@C254YJQWlw{8GB3-IBwjTQqJ}Q+ z5BbCX$iwX!e~b;KL0b2$SM0i4>@G)*rTXea6|dpN%d7KI(`(d{WIm4EnzItsS|~vk zp!}`}yh}uwRcu>XvA4Aa2g6Ml^rmfpKO3uP2K}9ESn{>NcGZK1*IsBXx@_D{(>Pdc zrH}{lzcZ*M#Op}4?j{Km@jTRUSH#n3t<^L?7TxOk*ju7JEjE(6%k--4@AZ%PyZx*D zo&Gd?-7!B}@s7o<2KYU8F^bP0(?XaNGAKxhs)A%#`^c8)$&8`*s=E}4A z!wYHKZTUC)bCxt7U6VAF(nxxaNu4=HIy2u~J%u(-z)oY?iI#d$?_Z5Zhi;8QN8IJu zZTgnf*h|im7P|EaRbBLhs_&d#xYxND)ay>O?p8g=t3%)8pz7A0YJ?W8rcs>C3x%Cp zb8)G-kke_QH4B_fw`=>6Snu?w{X3um+m(31*SzS%suOlCpKbr)1foN?V{@GS8Ls$F z&?pz>(KfrLR0Za#wsxT&2>zhByI_T?RtqTOu??mMZz@TEE|s?8j1_qFXhf--Gf?cN*WdPn6sF~rb3JGE`a5Qw+tlYONfQly z%F$Vz>+iS&y@uPgDK^AQv`vehw_6M!)^v-CEZ*35M=1)PObso&hHRU&?HAjw-Epbm z6Eyhw)}q(Fb;mBP)K76fV85HOmw537uT5nGl=Y-#dVG`nqSOy)Ft=g5MT@~TkquSu z$RA=?mus1lX|HTX;P2`#@EJA%m79aiI2CLU5yhLF|Mu**@ZaITlVtj&k*Uw9LvnV; zI6HY>c8NYg{%wkhABL{qE~9Id=n_PYQq|q*d8&|}1DqbRdgv)$To2$sEFm8%>Q1^h z38mJB?SkW`plFG0LTJ==D|z-iGEXr($%x|f-9^E+H#+;oXTkHQ;my1D3DsDiLdHKt z1O2hGlx$QP4?+Ity1kgPavDPax;vr%H#)j5k@=kg$n4(7i68cyl~z3sDuiV!x^eIm zO?!nj^Anw#zz#|b2>UmGA@D9%0R-D@uX?PwjjA8TRtxun5@P^BsT(hQX`8*UBCtUx zc**!|04fv;;2b`}hVcad-DcCJ-JDym|1|sv4`RvZA(uc7;2ZR=&Bm#>M2jIDbUV{& z*|5Zzy}qX`y+6!Gms<5YS7p#UUP+@WNjpv2;hyc=w)r1$PjE8oeNyTG2OoKt`|-2R+;Ycbs_oig;dRv@EZJ6*3-1&g*%ZGqaISj6*p+K!xNM+ zf`oLniM}CSKAS*_cd1zqssZ{J&v4O=8+aT;BT2R5DnaClRwE6!JIJ;Dv?1ww=nxyz zZ0k5_$dvS_40w>@1D1xrK(upY8Xl%cq5ej>?>g&oRMJQj$93X$VeSp7OWX7CK1r`X z-6sa$S}kOWdyI_(9M@~Y9~f6J?Ky_${I%6f75LUAJKXpE3O*#lS;Bo=Nk)p{AW{r{ z%6%mC=$~nS7McSsgCUXhFGjW14l40_Vi9K9ON;rV_`?`^!U~MhN@sDSjNdi@#+jRQ zDCXeE(d1GTLqA)M;EgR$sOdd-&pY?Fl9Wb&DU5{^HR`KQ)rVZFFnY;&>bt3f@Pp%4 zt6np87waC4q-YrFHfqj&Ft>M~J2&q<;0K8qST1@_EAeVh8Yw8W>ZHEs2=9e@;wVXY z3XD$_r^pJ#^6GQHmVrjqc|;v@l983M0(rk??UYt*pDV2O8uK zeoYAWQJyt?EB;YXLH1{((Dy4qOX_^uc@5CvId7SQd^g?gK%?)E>Z=49@het#m|`cS zbh;=4DfF9cvj}g@gv|P=g@vW|7#M9t@kt`u!W-o*O5J&yvsk1%^v13ZdG6j2{tU(W zPxNlQk8^U%Imhw#s2NekxrYAD5UG5nLkH%!bL zCbIcVOU$p8jd2ik!@z7%sUkMUa|&jSzKk&|v2L$eD;pCa==8vBP$|JicMHOX1tw~< z?KkjI1UDy{2Hn%ghbM@$OevxK-9Jpq^W%;#^CRA6%5CGnca&152c2zA@ofKf>?IFG z=lF!c%u#2iW5{JsIq@K*gOHdX)ezCXv3KTqRd+VDtw%cAVpei?z^|zUwwJ*L@u;AXj+S6s84HY z?2r=b8Qnv`%i=72KQYNGGnyMdibN4B3P+%O;VAxO#1!sEO0V!xI7xc@k#H~N-IHm~ zcDN6T;qT%*GQ`VF>pjs94^WYD)xcnla3JDEnp`mP7TG+l#qbcaD@jPK*KJyldf`E2 zw<=KDXapd_WIT#8Ec8AfAyaXXPZI|t7>DpUNcbo8lgFOz-;HQaOgbR*lsI{2w!&>OdyP6C3?k&;*EmHX`X^8>b$2DFTD6n8-`lZ5UR*JD<-;;{2^fc=% z%5B)+=(1ZFEpl=}+-=CHx})`z8MO%lz+G_}{Pczh9%j zO4KnRN!TFQ!(rDW)Ic@V({mtUZ{_xIRiLAZzAM2Ph#B6^^pUJD19UxM` z4zv5=3H<@~>zm+LIGBaZMKRg;I7yGUb% zhcZ*bR-%~>wh}RQ&x;un!%`B9XM)2e6e=?{s#!5-9WM5f*Z+~4^|iFXX8XrVJA2^B z%#_ujbGl4864SKVnKm+4n8&p!6pd;OXE+aDH`cj@??#mZmVW?G+MyXDwL{ZMmP1pT z1G0~!IQf@Chh|UUUV9IP%G`SJtC$OL$V@p@HJ-_;B8KM1tJ=5qm)WS>hb0xosL3`B zByLQ}ZAn`Iael~%v(hon32PlmGhtw*WoDmLW>Byn3|A!nhNO&sc_Z$a!1hp zW-Myii>#O0nQsilhm5Fy6@`jtW9W^ImJm^&J8dawZw8D` z=Ib&YI=}i<=;V>`OPsEp2eekHB3~$j+|(3h9+0xiAos`ns8t5JmG-G_R7$cMSt|=r zTxdqDPbeH&3&gj5mqL6y=!qjf{C4g{9fP3;Fs!M2f91V(H$oa ze`uA;1+S{$oq-X%#AgJ85I>As9)XZ;70;?$Ie2)MF3aAz30SHqNG4d#qnL3co;;T6 zcx4bx$16@M_vovn05(|5^4F-@c|@mEP!BRS{3EM z_$n~1tGA)jCzv}>nRf9?hX;P{h$ZuUesX^gXN-h*Fg`!nsbdDdS^7v_Ijx5bA2c$2Mj=CU5NRpMutJ6UgbWXxz9xV}-L0)Iww5buUdnkbZ|f6x zW1&du^ZEE%5F-ufk*_AfJY0(Pn%;OCVe1T67`1LhC`b-k*u7i9B}0U@=;Lhz@h)M; zTTrMNX3!hk1_Nf?ciP!lc8!|nzgFti0gjJ^Z|0Pjb_WGSsDb+gB4Ho3N+6wqH%xerhz zVyQyI>jWdTZj@M1QE&a*DCl<~Zo4~V6|WqU{G~3tDMPvKB3hV;^}f1Y(*Y{0AZ}k3hbK#0^FuyKU{0AY{*w0U=t^ z6b_+v$D%W7D57YE&HD=?yB{d>g0rHUEE*B35?$IB*YGqN=_{{k)hUqQy(1I>lFbNd z_R@I>^Ppq|QK4rPliWCnz!WB#p+bFPlGpI|>;gybr?yrLQpNU2YoRLNCAo+tgF;=r z;&p>P`uWQSVo(B)+fb+&c+eYL!2mq&DgYh>GiFpc|AkV|&B4a4oZ76-&#Afs8`N@r zf{p9?s8xaurL4ucAy0~&>r&>TxKMAfaS`+huyKi=IN0D%n+G;-iD_@BSGlx0DBS30 zc1u^j4!|)jOui=5rER*iSi>7E2aQhXF=l;JPN$d@qq6To1K6D+tBU3D<4Ik1%S^c& z7CR<)_GARcfyj)t^KXd17Wl+MB33Gpi1=ls_j_6b10a##L7{$;$cK4ei_Brs-g!DR z$x}@IG?ac}EtGy{U`o4NJet3`PK z+%%!{TR|K}F`WH7i1>bx)2q(%o|^$q)u@Hde{r=QRnK1x623WvoalqUBA}GBxawdX z1Xf7X?h>wi8eMHzeMU!qAbC+{J!=bczJO08ZI#7Jx{>&_GMeR|OtUG*=D|)uf{EBOAQs*wcG}vU@gcdskrDo-Qu zzT6LEw-@?!O`aEm^l`a!O9NtV1&ZOYvf45lr+yldygVnxa#m%d+`(Cez&o~I(VJYO zoGk*x>*UnXpZ{R*CVeRex#p^)Z&*NxYkhg^G zoDmL|5%%Erg{UahHzdC(u(teVRR1Z6-0o{xH7Up0zopAEwnb(hCA0Y;-@yV=bs+6w zk*Nd1+R1>h@~08uC$$&`0NYQaP`_aNV?3_~wkNC>mu#4!fillst@WR;h2C!n8n&_h z{D>AhH-)yyxlllBe;M0;yAa=9?X zNaNM_#1Heye=Gka&dgbIaWF~cf?IES+0Wznkyev-F;|im9HH^XRz%0H(XzGhhc;E+ zt)smtPPATmUTXkiI#u{l`dEGd@_r<4@Bn1o*c2JE-9KUmAJSx~fyaojJ!a-uQHjR- zfRuU9b!R8ek$ugKIrxx5^ewpt4g1ywc4?BM*8_|-l{I?tT(H*N;N<`$A53gL+XhiT zOS17y2Xl`NA}%$Mn59A+JCJyVR1LmcywO@&^kTE_i#CS)(M4yag~RZyXm8?2t$NKt zyq7C&7j)apzQ1}P5lD3VN)##{a?l%F0fB&DdfHh#OGdTxHFvi;YGiU3r!wpFb6r4< zOkT#bmXA!H>}zDwv7cX-;ww*i#GaN4@D`hQ?pbok%FjAMs!yU2jVY`Iwe~MZFd+hT`&?m+|pQ0x| z_Tf*PH}<(XjRx6MGtlw|S#{U(&!&tcI(LI;GJEYX6ro!!Fp0&@qR$aslNf&K-=_b4 z8|`jeh-|+qAAo&Jm)&xLThG2i!&dlr#Gx3?{e1R?hy@I)*@}0C82ZG3&)B!{YoK>y z(Ruh^s8UP`{0vWON6gsj!O3hHAyX4VDttY~^2tWx3tDOeguq^nLS_Bh4x+r0=e0s$2Rd~p&qdcPQ>^Hf z;bv(q+$;{vjd2_Ky+^q@X`_?jD~Pn8r#}>Xm-BtF*e@D7JN)82=-yzz$WW#5i)}n9 zzt~|Glz-fxSWT73u`3RlxERUU5Lc+0oH@tQoE{F+#Qho$4`7e$$bmS8lP-q{(pC*SEyNj# zNfp<4s2B+}Q&!~6EPClh&uchyFFJXAoKF9|5f4Y{>`z3^JXqP9_=1VHCD;^!OH;a3 zK3-V)t;hLZkQ;BMsuvJXN0<(0kW%#K8k@9h9Gt0v)NvlhISPaj#W?vHE8wU*QFa^% z$uA91j0KHmD|MPUE)sXP6vlk=Zc9##dIbccR^C znZf^`R{s8DAGF)~`;UESy)A9pD=*;gj#b4yzrq`<)L5#x=NEa_^0?=6Cm0c{Gg2Jd zNS&k~#IzT>UANbkV zfr?FW$}2A9VLk4#;-gu+{;oq~_MR;kMLeV!_;>hA9Tp4<}d&(PV+^@&q)P5x)z?R_(+>AjER`%bPz zu9FwLJ^D<)Ztv^*18mE+U(V(Ab?EsIG(Us8IwOnlpQ)O>tNS7nH`vwXbWpgtpW-{p z%^9YZi`zDCT$~~khVUzr@xldomXSX#PBIoPefh%}(H?anFN}gvxKs zo#!J3Q+szuuo(xocg~*Kl=gB3;=Fsi#53;u~~I=*dm#Nk+u&ol0WaL68jQ z$qOP21~Tu{Z!CqE}U`W)ekIe9Uqr)I*f{6+V> z;~=qG3zvbr>aKWFdR(D{%j}`%a*__W&UaS=Hk?GQxQgu~v+R%x#M43)jEJx~HA&jI zm7Wcy*cMrDpTSiaDvwvg&lY`eJDaSwVqC(EeIlZ+1-4tI@VzPvY*gL|k+iXKCaSj5 zpq|iS({#6Lt<8pCOS?}Jy@LiD*^A&(K*(}jnJF~+4E8(c4K;y_S4k83m(L|gN^$x_TI>!Lu|iyDS#Al(nTvVsY5jnC(WVwBwb-jCu^c! z&s{;v7@DK%5lciLp96%R;F@5%eS?j)(xthRbNrIstFkXEUK~ep#m7u%9ajiK4S1{u zmkSHYTeS@FT5#uY?oFjZVT%jOcL9H zi;QvSb!(+r(JBeS@&xRz@#2PCrwaG-6t3*l`X;HFc&%Dg!KLlUwU2IjOuUL+l50s7 z8>)gNpj~083k%f}x?B>BNGeBES3$Si4Q3Ktm%@)7M)o~2TZLZ`*?zdqrsxSD!PW5m zLO0xZj@oKy@`>2Jh^7)h&unM=slP#U8p}|`da#1aZ|~iAJ)3NL%?f&nhhAD0nn)>h zBXNbg279)jrp@Hkv13S1=9{ayVW}}6#mneXhbbo~068nTpA*fKqB%y9K6l;m7ek(t z@lrKcJ*AlHU#P05gO^EV&wKHF;H69a8!!mR{B)&`kB#9HPV}N$>bK8~vT5k#N=0{0 z%|M0EeB+*)eaR|r_PkW_gJr*t|8T4IE}AfGv)z2lT1DM+X>`3o~}1=VlG>-Lb_XrS?8T` z7dJ^z8SL4qp$D&m0^h?$+*jCPoG{^@uXwo8xL$EH9_}cCDvvgYhSCY1uXJQ=ku=^u2_ zcTnT$Ba|qf!>7nGeh_~WHb%+(t{>FNUtCH2=fhd>_i%r=;fBFsdDpnvtSEQ!>r0Vt zcP;MUrgX^?tg0+42!J-W%!G#1f5`Xv)l~fcs*vt?3F#6Tei%MK zEI*`EZ9_WxHl)+#LOOyjq%%`OI#?y7&5I%JaO4Z6Lt023($cVymX3uqi@>K~LJG2k z6p0B5TZaU|TWpWrA$Sw*!6nz+dQc}6DP;FlKA{VCipU4`M+aJ2jOx0N@vMh(i8}XK zrp7V#RbJ>orhd4vIBmlq9nRM!-vCL#D$4^_;I^v~t_K!#1#LERmpFI@c;HQ#C_4)a vgFD<|tDve0I+ggKHqM#k37yRQ#YE7k*0Dqf{cxH3`*@A~hcvaKHRt~qH_!m$ literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.opendss.substation.doctree b/docs/.doctrees/dragonfly_energy.opendss.substation.doctree new file mode 100644 index 0000000000000000000000000000000000000000..266259c9d1de969b618b46af21a7644b22d606be GIT binary patch literal 41088 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 In+a literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.properties.model.doctree b/docs/.doctrees/dragonfly_energy.properties.model.doctree new file mode 100644 index 0000000000000000000000000000000000000000..b176788705fb689a04f7f82d72fae6c2ae4a0bbe GIT binary patch literal 78550 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 E2dai_(f|Me literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.properties.room2d.doctree b/docs/.doctrees/dragonfly_energy.properties.room2d.doctree new file mode 100644 index 0000000000000000000000000000000000000000..9fbd7decbac8c76b27dec45e90693a88152c97dc GIT binary patch literal 65396 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℘zTH{Hxb%$_?~;3E#s&3itwhwvL!83tN#(fQo6^I26OMA93198s^np{ z$mHNv!kiQzV2&3u6wE!1N;%AZo}L)Yv8PdBPSG6tRIoEdQ%XCuf5~18p!w=6) zYO+D@$@6}2mgJ)!#$AyyG)tDU{1EpiqG8BZ)gR)%YUQvRRQkY-swoO_Ur`mrD^Bay zuxw+GIx#3qzSJGuw-w)mr9nM!mbti2tL`;A^9c^8*ou}$Qy@0ttF<{qPxmUMUgA=<0JaY+01BpR z0Tc?RN@D<4b14pm)%!p($Lg!;iD5N+8U?ErJws#lQM!A3X=Wj>9Uh`VL^d-2#(9s- zjQoCpd`Si%v&_qn!#7$jraunfZso8#nRFbcYKr3UVO2rAQgm#=?*&qMKwb8%d#D-3 z+~8oV1rxYbj19JL#LMLX+dLEH7<(EuXJafAfrQpYB$We4$pt#!>xiMOfujknY>|qw z<3eAYAeOmgOhFEuPwVXcg0|wYdM)MPBf$46#tc}URr8Q8&MomV%ea6;XWMFs%kSpI zg?fB(sOyA_VdUW~WSXL^HodU1hbAWHTR1kkG~4m&v@gS}dlej|T&YEiPA9~f{R(gW zk*oX0{U0w>p%z*^tk4LGwa^Mdu{0h)F_-*MQ2Yca=1}|_^u(Z;J&gjzik_jN`0l6~ zx%I?BtxJT=Bka29r70Vz&;K>|Y25U~?W|?#X=N=xjDN{$ZT(^VkE|SpV4SKc3gf@0 zDp&!#F4DBd;ME8lZ%a!A)dJ+xKIyLTB_)Z$F<(nD_!<>sWBwQLayc-60Q2T9!1qB& zwhNFZAn6hOEpkeaK=KF-c#hc3@(2tpy_Uw>xWKP7KLZ4n=+AVO2pv0!8sE+ERD_S) z=Ao@4mZFvYLqT?NXW?1O!JUQwu6VYZV{+&&!^KiWz&&2bP`Ed_RpQ=edSbZ8o<_kv zMbFT<_x6;Fl9mYgZXbR~nnF}I@_pgFAEKtR(+~RgWeizU3tN8d+Y75Tqh9^7?=@Bq ztFfgIVX2y;*mtF>AYQ39U=3-vXDJuxm-)T5{3c&t{B(S=ojH;(?k_>GXX}$4wgU3Ff?5# zM3?%C>Erz+l7$ce{>9L{;o$;cCLT3{ei>@gf@%#bC>lCzK@}Q0OCy5|!KFQv3-KT* z=0oR)=!v-y>}eDiLeaA{E`+p*rHN`UkqaS+`oG16Q0y#)3!w^Iei!0XR*UQJLVViF zQOJd$YKpoLkEse)mi!CeR~$lyy z3n8VzU5Nh(N(#CVGNW`M{tQ{A3n94#7(7Z07jYqO&2k~$BF=fSg6pUshZxjwCo{VW zn4;LW53!U*YD;)Ya8%rhc!Y9rC*nmVj$%%PIFvz7*)O9Lu~ao_L4A8zL6H-o1y#t2 zkY)xaf=hcSCt}q$=|rriC+0-3r%{}U40^0(dm^CX-)oK|ldOx=8pkSiIFj9zLz^ZQ z`I{B_>}eSC{f*MVH5F6-HSt~*xj4YD&pd#YKH{c?0~FADZS}x>v)ZY9AWBN0nNQ9=}KoGmpEfB3Azt)2I`u;#rpAh*zC}y(f#bYck*FCl>Htt%)&kohMI-aa_+H}}hS(J4=-YDPHYYne^JYJ83$>?V7 zup4i!HY*)mVII=G!wsD3U&Vb^Z*%J%FI3mV$K%aTgjurgaewpic!Hfy=HehTlr&Mr zKq!pd`4)a`fEXf>>dn^9bmP?ryYU82LK*d*LV}X`*=g7D3kL~T$}?`|6nzCLW1zXc z*p0W%q8K{*#rXJ8yeY&G1o6r88AK=NyAQ>aA?E2?*sV4{kBlJ-+{xcy3Xi?PDO-_W zW~K&aP@l*^w#QyqOaC~%wQ~)W)-Qr@kA$@J@AGDSjW?iUzz+^_S)@c zyX?D-YTau?14L>i>c*S7m@4RHE|fT3F*IyBW7zg>-fhZFJ;Ru9Hm#&2A%@3DG!Q+O3L0H;H8B*;*aU zo$SUt=n0jCUYpWDH&j{`D&Np{7u3&VtK+TI-e5V6IT&KSHeZXnw{O`KPqw^P8Lh-a zE5#CeRI-uY%($SPnnwHzKZ;u6p@RqUI-KTL#!olfb7)Z)QA$PtQkF5D4fRA&$9lX! zaOJCi8uFZM&sMDB>5VS_Dp@=luS+I-%4<*8yl9ryfezuIAI;ZM*+k^dpcPdkzk6(b zybCrtUsjD%F;EU$WFcqcE#YD#a?h02)%M+ZZM{jRzcHM5(a_%AL8}fSsO{`G|5>g# zE3Odju8Qx19w?r-H%OU@5V=ovTBu?Y)J3%j^5@;aSy)fAQfth@21LKGjXH|3Gh-#I z&0{hjb-BDTu4P>kOa>DkRkYwmP~dxBggP#&Al0d|H}BT!Ww%d^8@-rcZUabw|GDoGzN5m zV?cLC1$3uWK*#Y1bX-3>u$7&P8_kZy3<5gmAfU~Z0qwX9Xpc%j z8(9Kc%^T2?-+-1H1+*S1pb5x;W+?-T#Re3x4QNOe(73A;Z!#MlGlNZ7pu&16YUun8 z^{p};w>R?*PX{YRBb}dV)>S)ZNiVcss?-yS5+`J>EYr3``GCoG)J3OvkzJPf0&fL9 zf2G->ejTnsrCF!7HfRgL{&hEq_YcEsbeZSZ4-Ojx@jyr+lph1B-xZUGGk(|7iLM2$+sgs1_v5;3KTl}ajQ#l#{nF)=+(x9i?kLKS;GUw^Ov`|&;cfsyxp;S($Pe{6HqcD>e#3A@o~1q~guD5mH+O4v&&^{goov`k7*$ULCyI!*qI<4-#UABp;$6hmtJrZI zdQ+Vkcp*Hj_8Jkvytdx7qX>m~9%!k_wU`0rRBbhC_TPyO1V?qU+q9?zN!mN`)%S zZ9>SX60*YfX_}5kKmkOG-M~Q*5NH6bD(7&^YxT#`t}c6ZUpi0Z4%5x0zQ6?7b`A7V z-N3g}BP*bE@TL}d5URKnru50>xg%BGAc}We^`HgncesA4MNWLpp`hjL;?$~Qz|Fi{ zyVVL}JEOwbwRn~SgAZC$OVQH$Dk-Pva)RjiAzy%w^>wcd6%!drAT z&5xQi$G{0Zq9X%lw$f6}geToY$Lt}^HEiYau5F4lu}%b*Iog?Wiuq&g#B6gPhXWeE z9XgQ{9&@_X)Z}i*B9d9eP!JBT@-_%k!m5$lRhG;hVHfo0RfX_Ds%nb-MlnUI zY(02&97yG}VH;_3oG18i$0U~f>+U0j^ml8dyNqO>gEhv%%EGiQm**821#k7tKTFK)OQUmDEBl ziy@=hb|!vk`2VyRezvmJD@$JhpwGZRD3m2d!#_sF&wy^9Q#zV$%hf;<&@U#{PRmwP zwCsJM!T4G+819#Q6aoS9_nfD;a0(ID$nCOW(o6)eyhe?UCq3Bn#e=bxK`+j}Cx;tj zqh5=9SOycUAvLUq5kK@uFO`f0L7KKZ&A4{VZg!mXsBCN0X}5zgu0^wU7{93#kQ?_f z$<~WvGR4X;L%{Ni?5tT#!K)EewS-CW6O74+dm6(@{i#G5lM{Y7EXu?&&pBR)^W9~e z)nmpsp#@dW><%g*nsBgroK zFI%}{g$7NSZ39*J*yLBjYX)m|S%vgSFy$jS=%y4N8W;E?)179M%Q>cA zsl`E^kRL}~|1z4_F&a z9u%nEG^+czP}dX|ZD*qrxryZX2QuTP6&4(OJ~&&|o+FDtH!i%C6mf{mw^27c{G0Gk znbJ$x$G-?Q5i=4q&Dvh8>)%BMYf%u-wZY}m9b)TI;+$wVy}AcU;T4YCVGECAz^~*A zPEDGgKsfQK$?6Jfn&^I-=uWl_Toj;_n4-)dBX)(q?;jD9tOSsBUF2b{}BDN)7=fm024ts$oWqNjk%s#;`RC|=t?Kf zhmZ0yV`Qyr&@Z#S%{8yxK+cvmK5k7KVPQQ89l>Ol&_Gt~+Ob7dBRnFGuyi0U_>f|) zO;VfH5Re6}8Dm)KpGmcran}5&hQimU1iqfcKfn_rG3z@IJZi*IKD|ll=Iw0XNkFIR zn(f#yjG1hUkn|n?$N41FO4^JJNX30j!1GaF)qev2DBC1?H6hmBTk$gMMhe=w@V4fr z9LL&kgu{oOIH6x)MQx|Nt(y_}MwCpUA41nyw@q8*(e0+P z3NN#cd(EcR0WVOsWCD3zTZqedTgP3m?pj`CAr`NM4v$A$6qO%yXfWF%Tkq97O*^!v zI!H%SN{5^%3(BwF^k(hYvEGbHOjK?ZKH@$;C&_^R9~!7*y5bVPnDu`qHKzVgl1d{xi=F<`^eo48IZ;y5RNAHgVIt2C|APbc`rD!^ z>F7QN-hY><`fCI9`ZiHjSuJIap}Uc_n)X^AC9LulJnEd0sgqUp>|&k#+gG`SYj6CM z)gP6L^mCDghc9Xx3%1_qL7BW%nWm<-D$VQVR63Vx@AMxa1e|-I0xF!15@GfXJP1{iB=Pb(#|;MjR3>)ki714n|xeAS}5%c}Mb&hvAl7V>Xy&_KHW z`g!&+p=OcJ+b3~JqLXSFv2z=$fC(2NyWWuWTvf^V4<{|w=~0DP>H@7%x`cHj#7@gu z)%}F~$y8jc5~?}BTG^v~@TU_bt&)iAo03E>$^h8^D8bG<^Uv&2 zmxZ0BBJlYno7lOz8EXw-I+;MyD3VRa+_U*6{}I35uER(+% z72U`E%c+}Z(5-(3J$(sJtRS1tG*>>@^Oz&6@N z3B(K6p$2>3e8FA~x@)l0u0aM{%AZhd0yjnA4qKnn4ab^;3LRp<%GHN+C5dS`)VEF7z9PlaA%#(|Gy$9C^Fsi-$9JG&U8%KVm9(HwrX zl*7v-x0$3Z``jt+9u?xgHzGhi}j%K$6vG--es)u6lNkh})Jxu|+Mev^f4BZOv>96oq=slI`9_2!vQ>?-a zKT1&vjN2fB6-Df(A2m5i;%+Q^3h%+rPkv2G8`WG^%5W|2nicZWf(TE+hkHA+_T{SO!; z54ePpUG!!5q%470?#&hV9Hz6XNWyq^`1o^`dN4~1s@&xpMaD%SZzc6RtL@mZ%+ z3Kd!$Ja2SW+pwceY67~xN@TFYBCIyv^0kbSDm$1J%K(BHMTj^w_1IlMD zlikYp<~Qmem^Oh+5tz=>6Aw)J(@6xTG7_8bqTb#1F>L3gs0(o^&KAwqC<(qG@#y@M z(s@%liBR-#uJM`3hg_>Eel7>whddmui=B22r%{3?P8kNRYxefWqT6!2Q(LH z$|#Jqz?Da!Z%^8u@>$?~%4Qc5FB*&pJt64kOgmXYhj0~LK~csm(&YGHg3=-4&-bGd z%)!5_RWz1=Y{CD7^3GrAIVOQ~3%>09$4Td9=N0^CN{8^*z{^XGQhrWB4qmJy&B*$F z0t-4Zuq{`DdT6sXrB)jhJU&YJID`^L%Q_&Na1G?p3hhNzeR0 zOFJK$PGZ<$=u}=eoi@;V#_!U+mmqCWwBC}dR|?l#G$1`0gSP^(MaURz8&Mg9op>tD z7!;TZl`ME!u8lGB1d1%s7r!bwtM7Wt&9`9FtxX4q$^0LI^~VYW_D*9lMGa@!^)QI= z8!Io;b>Q2kZg}|8UOQ%g^#uellgHwH(I+t7JGSLMR+SD@9O|(pO-0@~y z1WY_K!l7td2ND#bC>ib>_CSM1*a%N=rkepaA>)^=8YU!Kpx!ivUO6m<{41!%xd&*0 zNCWIIYIfw-VJ4}vBR5f_1-;-g;EA|BZkwg&`^>aagGW{9TB(RcH_+xsSWrD<0Cqs2u3vk z;KNnahI|7lQpxa>9yiF1^%GY0MspLrbivb^Ak&*uxia0aVR-99af8eO)zBzE-lsRF zj&ir(P5Y@Pt^cPi7+6z4nU6k{)v6_n*kXT0rM&LpL@G5BD&_UdylQ#M>)9N)lnZUk z3feqV-UR!{&J0%XmB6Yd#Pu>{#4RrJI0;E~RCgV^O-2ixGPM)dBt%uc$HG6vw;5G% zdKhP?NFCUu_#vsu7)oTDbS$dKEEoq+_U5Kgb3JS+LAmcViCBjB%TX^y=^>8#ymTtP zNsAKulgVX_Y>lWaWc_*hog7Q$2$knY1TU9%sgiGZ4bZDhzLEVKF!^@F0KLlOn=<+N zd9;j2r*?)Yhc>@a|K!`>Vtyj|_Emb~$v6JAbji2daaj`%9^;hQf+XA~=eq$UnZ`*Z z+4A@MPb6Je;l@LpV~V$3|wS$ zV;fU=6u8p4mYla$SLeUhsm2P&xD80yK{JRq41@UcgsM%AL}tao zBT&D`0Ig?5|Jnt>9=!OI?M4Ir=3#*5d#okIYrt^FImE^K7lP!=bC^aefu~{(Pp#xR zOar@91B|s5sK-ubqm>qk^6}(~v(ifQb$TDiB!$!ayY$4JUjDRnPVb!yvg?^&6Qoa* z&fE1(CUX+5Z^5EO(sfmAXeQ@ZtsDDF7qY7|S2~KLa>HEgxSr!e9LwclR5U|zgHtv3F|VO_!VGD@-zdb*gS>{G>5ochTHx>h z2O15!*ZO&0*PJ7XLeCs^VbAS|{<^hkX3nr?{(kT^Xf)g$i*<6Z=blTXpYH+Y0?%Eu zW1;7+C*R|_e-_kQ1kZf}#1NkQm3S)l-1X!W&pjzJJa;7*&?T`7gB|T(vGO(rE!J4}pFL<`L?Eefrd1tI5YuHe}mT zf_9;LQ}GdK)Egfqg%lsr4~^=xN>N=9!)-&OLF1z>ysj}vxgm z^uEy0?41uZ<6?$=_w!y?-g*8ClX_t5z@W|PlX|EzM53g?e;wV zVFbF0CZO$4q)zM`=-zmkw)FPBCWQhk7aNawj26*~$gOux?zhC{BT2NiFr8`Pct@#l zWV{l-op-q!0Fdl$5?GLIQ8%}~e;A~yVDK?&w6MY8>&Pz2?QsS(iG??8QI?-n6R82U zKqt<3isPQ(TI@;{Uv^WM`{W0S+ycrSYFTsm*`d%OW0R-QC_hM~H<{SvAhx6}Ab?st zvSSsiauqy&lFvKsTxG;a1&>eis^!7s=d%`@$azB$G#%P{7|^z2>_vBRk0;-ch~1s7 zb_Z9j6X7E_=rkJ^Ig}M_OQyRGJb8>4t~cGpj*JlPP`8^%#Wm(=f3orp_=e$|?Pese z?B*RNETVfNy+)3FWNrxN-fJ$O^!gc+XL?^~B77r5@N(oz{&|igH!rrOHyQqUVwqr6 z<0K12f5!Yrj*xQP$*@{5W@(oytp4}_y~?nf6x@Je^`isyD#L1})AJ+btmMgsTxGlS z8}$#XtuYl=pHELbtmaQk7gp1^>r!Dg^!vh|AU?8C;k7xllL)h~AIwiRN2{7Y)atK} zug@vNp$ad`D`^Sc2hK3nOj`2F` z5Z@g~w<5m#RXi2Ocje-#;=FUqB;APj6s-_ETtQ?TWJ}@!74H=s&P?_xa(eWJeRt@y zpGnxapnYmVc~HWn>|k0)WsE0}{+7Es0wLd_3Aw0I;0K05u8IQRPmRi=K;yd7>rHJc z7MKj)A;yw-_0UsJ{vp>xPwQ0aou>;m|2#buh|)9vBpT&McJ#(Hneg5(n@k;18~`Rg zyKHx*4lTHQhyNs>TB#KH(wikh4d~52HbAe^n^nB21hRC>YLQ53ru;_zz1in6Ke+ntur)uCvb4O{4}OU_Y?w>fm#g9c#cr3dF81<4V;Gz&$I+%n13HdJpu>JH%K{~e zb8aXgrR&&1qkPwq-k5v{*KyGn1+rt6I%(Xm4Eem%mNpYzDZi5FIG|s7-vGTzzf!So zzKfWhipr8E);_C&#aF!fSE6&jCM0hDe+u&xe&y5j#QjSCv~+&uFUG;bUGab2e0@nd ziIeaj3qF#gpi?_}ui+~=z3$`MWCr5QMDklZHeUwGOo2)>Z@HWJmq}apu~XYkOz@C( z4L7AxD12+3tIT_yI@+z8E2n&2QlL@%?F3Cjq$$6FMo@u$H`e^Hyz~5xHL`QPv1Wub zkOD&f(h&T2=^#UItr5c)t5b7p&2tZU7w^pXixn3Z9uUz} z&uU`-O8{jNeBoEDSHAFWJQe!FiQ-WH@0e0S`U7_g+3=wLT=Gj_pLfrlPTUDwVw<|< zw487zb$LFnsm4c%k_()ZJn7KwG%vpra26{(leN_0kY%LXfcw1?zQy)lZyN@W%6q+; z8V%^ZKB-ixxfOygdos5{OyleJ27{=Zu0+aRY>c2i5ywL>#>WV)sxXxFrEs6l#L%hq z-g~lmDYi%)^BNu8*M{_~+CftlTOO?BPBh+MZh}=?0-0RZ1)3S}8w!ciJAMNi<$K5U z#^h~y#~)H#9!^orX6L+`y)6%)yhq0pw*C%%PM@(pk!u&r~EQM_jA1l6fzJ7OhHiZs2 z`_!rJw)O(j@2i>@<$E5z9U&m7y81x;tMq|*MS)>X!>?0~jFjn9;LemX>U$LabD0(y z$$lXBC_D{QCfUlFq@(bkNCsGjl;(mG$X4*A8J;>fnR=~;2dNxz;3#p z2u=m5KJp%f|FPeo&|#`D1=_IV)vAGGdZG!APt5{_jx>&F>5Y+?naYtAg7^;7o~YXxrF8+KMf8FDwD8Y7xM<1}$f9%5f^{3!*dR z%zO3hXK51Pf1X2X)V(-g)X|;E8g-iMDMOZt8PsyEVx9#5MIY7F$}|1Va{gJ(O&gT8 z-%L;3+ViKAu=bK4FrRsUR`V8q*tI%O3#~4UA}fFOJo}gsH&=`vin}(6?l>rP6>k3( zCWn3W)VAzm^8Kv&+4wF#x7r{E0aj3A!Z@|EX7FnP}S>bz8Ras#L1f==`f~Uv|8&+(B zjIg%8^5S$77P2Uf6(s^c{9vqR&pWSi=pkQ}+1?CTKQph}uv%jq6s>)`Z}z(ifPr4iKe>8)lo zfeUDG+j^^kZ5(&m&5jdwAMJ{Z&DdzriE$LEd&u2dZ#&jymv(-`h3!AHF8**1Qx z$LXOMQ+1}j6J54)PnWG1Q>bCwqo`1kKRaO)zc$7}y*6dnkJ4LAWdw5$=eq3lX>>z} zp^TRgv5gV@>Q-mAb^=+h+3rJZ6Mf8~UBkC5XVEZ1hdV@x({y-AjlPap=b&1jlYWtD%uXX1zawk&Qx8IXSlnrYb1)2)F7PmlxOEy}0wW%M|Bf?+JIXfM9jqzn zBDTr{yKQWAX4{le5-bVC@&da1KWyRH8oJrcOE|L=^>tA@aypHmc4C$o>NNUHMY zmYhrKaqXBFd4gp(W7Rmard-$wC_ueksPEQyl zazZYfPK$bLfaL2#`#4A?ejZrKwvfDmb6PWC#HKgv#odFaUCcJM`A6@j9Y`rYErUTe zP|1{yxszzHGu=3DNBj2dL2)$Eo{Qa}H4%g}kf?1`lTQFOYq2v6^28v=I+TxJc-bp~ z&rRWU9pBV5yQdP}{Y9#Kx?qS{_NWt1cuqXc$ACiE~;^VV>`i< zv$aGxlM!lBn>gfQc3L!tkD{EYx%iw;lRl}_Wow!NvHk{pW&wisrVgY!0;0C^-{NPj z8Q`n50<}An@1_WO1C}`o(fVkojUhH+cCi-&|3VEs4DJc)UTYdWAoarOq$r}!RHm9Y zOT60*Y$1$mxJm-c%ueB=jwqhP3|z;FF~+t!Y8|aPv-m(n&2BXCtqIZ>53w!OGil?< zX-*5B_Ap!Rw2pOQsM$K9O(4GDL=Q^~kd3$&+u;m8#!7s%1(O12#r#W$;Ie7b=Ir!T zX$yzNc`bNO1CvyVzj!!u&xf(#?_mb7cE{ML zm`tMA-4S_f?Rlu^o)4RKHFqCPtIkHe2xhJO5NwOTW+Pmio$SF=B<_+or2#tbIlA|_ zj{gWQhV|b|e||uJUZ6kpv2y-tcAq{%=F>;Ye7Z*4r)#!-x|WY$py|_X20q<(;M2Jm zpU%bjv_H|O{fm5c)~D55o(1E1MxQ)xpWN~e+h_^~C)LKf2k|0)0r^A;=|5FZ@Pt_+ z>VZ=rNV8KxGm$l3^^8nmQhO}bF NDZ!3Nl`E(@@xR=mk8J<| literal 0 HcmV?d00001 diff --git a/docs/.doctrees/dragonfly_energy.reopt.doctree b/docs/.doctrees/dragonfly_energy.reopt.doctree new file mode 100644 index 0000000000000000000000000000000000000000..3a61f46508667c2df6f64d88aa1e379b9c22d94b GIT binary patch literal 141127 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..9e6f0f9ca41432b3eb13f1c59a103eecd579da57 GIT binary patch literal 1136581 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

s9WSNKHJ6BaDR#N0Vz@t5c$?X=xn8QhMN>7l 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 z

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

p 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 z zH!3&;`6nAV#4stBytxdQSgq-YhEsf>j=?Qq`&hszPFgIuSD3T+gqD;E!jE$PU1zF- zf!mKfBh$S7*ef&so){Y4ZQkOxPQLZ_$!Jj@-~o_*dH%UupBbU~<*9G(z4dk*DN}h@ z*4YR4Z|=3blIB~u(>Gn&&B6#1(=OW10{Dl9$Fw`gWv{SfE#$G|JM9D)9WQ&5Mk`$n z4aX^8pwzk=NtW;t*)V8K+5LSva2u1wA~Y%=b8iIq0E6z4+|>=^DIV*}Pk7GjY&aU8 z^D89`q;|PD;#SuTS`Zd%CP65^1gU2pnso;up#rXf;cA7G5M?a?f;e`R1DOP4?0oQ~ zu_Rf=jokvC@HeAcGx;*9!t2j!d#wkf@q`EEIbx{jfp)a`T2i_wZrGfbr*`fio9JDP zu|nvg8;gi-+F}EpkwUh4(FLto&9X-3`GGnwi4W-Xs<437ve zwqBe}#zW8>Cj#+sMGj#MD7e@187gmoN7B=cgVDO?bx4aXEV=YzuD$aa#0w5AozQPQ zmW5pSpd{LhJ-{>12a;g8BhRN*?V91~MmjIX9LvyRNpqv8-I03##L#BFfkEG%uvhjH z1>3ly3O09UO+mavxsXF&@ExND^-sgA?jfSPx! zFc1&x+VG!K1G@FHVz%lVFVINV>dJqOQY74q)xHpuUdp4E z#bs9k^g&{TC4ldn8D10zY^OADr}v74sZ||Qw$opZv-C^gAltjeoP%M(9=r`J;z6HT z`gaDDm8q@V$n!`XfH;Ok-pDcGM&hEFQk(>?ikaa2gDWyLRZ|*F_7|l$)keY)dFuoO z=ye8R1Z1Zo5o2P3(03bs;H2Wd1VfAU66&-T-11q(pwZZ$q|FmuW&S3>T4-8fwF@9c z8#eC5@8(GuZmjdNyu<1ZN~f)0nN$eJXY`!8D#9|JVG6PtgD_13I{KKI+ELTQO}`I+ zq8dtH4n|FR@DjFDjw1&ebmvMp}cDPhupUwfxoUs05%k z{MiyZ;bgbgcSdP}IBl$l7qj3l<8jNI3e?OHM$K8v+Jan;xw;$LqS;T;Nyh@1?=Mb# zjU(l0Fw_on!ik(S=i8YjMbE4*Cce}TTm*) zlc?RB*Y36=WPG~RAIxZB>Ni5!l49R zRbf88()$cy+@uN&4w(w^*_GZG2;s(@!grYw2AN5E&k^9u)*k@OpQ_&TE4^1($uUdX zQ?=orU+LW_x)wJ@g}AxWTO)*7~e17B}0KP`=#$eW&+nGYfwt+C$21V0ziruEPa7l ze$flKqkZB_DOi>t34FLz>^MTqf2uLWJUr%&`0|Y(`@|<8WAR?`;aEaKTKfZ-4iK^z zV*mpvtOFDA_JdV$%=9jdsu0CQgTg1%r(&=*y#55`AV z5Ntf!JDeO&uO#dt1U=T?!COx-plB1X$gdn?fRM9*idNZVHj_m-Xvy`I^^Y zkC;)ryUi$lyfUSAUJgI+qNt(57X39C6{$5|(%(5aqVN$ysvsNFhkZ;rZV?VfZz9+| zgt#k_?+mAi@~VWn-;%KRV23Vd<;vPUdW)b|2=k_CZ_>Jf2eH-tDHb^Xm1x*KgfyY+a9pEv%YAtz~*} zhFy4d4~ytw@HRsw*NM}u*u_|kZV5$#&Ys0n+KlG9oAa5-7&}f0kLvze6=SwEr#$v- z$^D8olG`QJ3nad)JDL)(v$ap(lbdvj2LnHX@n(y$$9w?Y-QNK!wZzUSuC4tp({s=# ztJCgcrM4>x`w88qr+v8Whplz(58eokp(^DiEGgaTx5hNbb~o3%>CVu%85Ck08KyXR zy4WYBI@^0%WN}D)fKCZNr|#=wke90i7XVq!bBi- zBQXCWG+WkASRgKcvqbY|RpZ092G|h(@CmF;^cN8Qq35M=*USX7s1b;h7%1EQ9b$byWmbKvY z9v+pLSaZbpTaxZ{Xgnb5Q|{uKcy!5JY6TUk6E%}g zTc;Co=G;Xo;o4D+!B!C05Z+u+{>~Sv_Bk3@o7J{X=m7)ksh#vWqG-cm2l=;%KxsF% zy`I&;d2!eXrWHSl=PnXkeA_f#7l*d<+QdM_(j&~Pv$nH{f82ZykRS$flC;fbV*m*_ zQ2i{s1K|7TVU@)al8do+yv>im{(k|__FK61KPQ5fwJ(I)yrzR=Nqvh%A~i3y&Ya7{ zPDG!^73YT^@(Cnp$sDz~WRI#SBWl;HeD6}rnKHJy7TF@UVz1cOkd z*!kQL7jG4XC9nbPO);N%(vv$f;8m(oXRCBIp?i<`0#iGWGg9+UYWgxQR;Moe_92=! z)rmwZiQ11jP^Bp7`^Lusl+?0ALV`}8b%(FI?wi(AW8LJ9KOz|p_n|&gM%SN%>P+#a zQWrLZn&xeYi`yrgQma(COHFmMF_L4Kgu%&OJ^f%^Pv>;bnr`Y{BA?8`;tnQwgigP! zz9mHA%qMHJN<4o6Z0uZgC@CFWS=lJLaWI(%X9o)TI-=c2L3elXrfdlKce+H;gQoOU z&F$5$7KhSf_g3p4yThp->d#R&rtUzm!pofxsfP7Z29q1)r{)K11y!-5zH(OtR<>Hrn7r(rg!g1>RJy+ki zJr&))7ET8AmB}qbq3b+gpl3N#Y{E_ebs;;^;-avDR)hOc*r=UQnGl7oa~6l|)2%b- zovOwW<2~|yAjZL>bK&{3XIsyYUh7PY{{Rvs$Dbkl*L285GVQp{4(>(!{iEUF z02rt|P#X!Ay7KkQt>>tgsC%I(Cu!Gu=?)BH^0B_o3K>T^; z-0OIHDwXo56raD4D+6(`m*PL*pgo1V8DyniBx zF(koszWPnMl=@5oW#V1I2CJJu_PHD^m$VAGwK@XiPv($b+A7?G)jhy{K8Gtror3PK zP67IK4qCflw8G))o2c;9MTLe{t#!V=`iD`cAZg?dh56OhU#r68Hw~+QWc7~%<_EL3 z^{(LuStM5tW$_NL8yeeY>EUAII}G%nZ#K|l|A%@0H-4xt{VOv!YkI%n$j2AP8!#JmNC=BL<@kCX0c zDWrkg2^oOS4a&w({)u_KGnqFLB$P?QFC)8sY(Mnt2Z<8$;Dettbsct<=u5B@XL!tCP{1&Msk%oxgf23&yNO zFP3Y3-lWCw&9uqU4AzOAa9T;&S7QP6i}+7Hbv#zOJV)h$JRBC)%q88jsn8XfL=qFa z93>)DgC1*K9a)C@kiWSQ!zmcnx=_v*TfHAL;{_8B@$;hQ+MD|jZMZ&@1}pPo7$eo~ zD#7D4T?sS>r87Qo3EV=RI1hL_zHk7e-Y8u)kgVGo-m+K^q;nY-Jp`|iB(V^7U(JASbj4ijHsu7mjS(-H66s?l8R?){uO zl6$Pjknk%FSudj;y7a~rDg~*e;yJvn85Iq=V$*<%c+;Hk1DxxU($%y|d#&U*jyCyD z+uUf9yb};$J}&bS0!t*KU4mschua6k;gq{Rd^ko22nGppSrl9TFUh@N|9~d7J(?YE zip7h2?{ou~`(V@2HgpPF!2{w}XMH$(G#u{1{`@o5oIX@MzJh{Np#$Nxs-bAEMd)me zjip(Ny{&Ehg|njMeB}i;bu*-nhjoTMKk2(Jai92F!OEjJZW%WwlLJ`SaDwL`S^fM~ z#KGWRE-E1sK#Tw+Q95lqVDF$&7tFxTB^VBaX%3SkT#{drL;LxQ}LSYS5(F80Ug)g!3EBv4gm?5!4|IhLGu^4Myj~9Re@} zWVFebO6_`0-BB@+2Q{P&wl56_d^y8;agbhZ^UubuUtU$pN1OOA!!Y$Nw}A*4wFUqN z$y!$~)*e_8wr4wllkDlmY=lA>lup&u*K0}XNUaQHFN*A2?Z`6qBa2;@jSOc>+y~b* zYzt}%G-19H#ih~oOYce-MGat;VZtd?0|6Xeb8a+cfj<1G2Gg873jm3bBm0;-qs*W+ zZCi*o0%_YV9)*_)tU4e2cGcwbgB(H9{?#n;xz#Vi<%Bl(OI=-G9l9dQ>*z7My1lxCqVHvk zY7+SYei4(1e*HErA(f%X*P^HLt)Y)BJ6vQ9fxYDEWFjcv%(3?bU^V%HPu5vYu9;QD zpt%9WLo;P7=cCn~Yf})A^7xeGB}^nLrlOVPcGyK8*UF(LjJ3mcF@8_>mNI12k1%lf zV;Cx&Maf~VwOpjd#dV)jTd4=(pkld*#D8C(!ig)3J9nBMQ;wTV6SY+M=-Dcam9hiC z`(&|5^v>)P<$9{5>42lPC}Ysnc(Y<-NH&IeUj7hRDO~SFT0G&D{%}4_(m=1?>NUi7 zX|k|ZGQ)*^uFjI3HRE(FXTC_YyOa$<^l5DEmiW;0117e{`Zm4bNg5HP;m5HeNW~z2 zn;(sEuMdXfXf8`FE&CD*Z+7h&j1g|$DqN}I&h)^6r#W{;T#?e``|=V;Rhm&KN)@)* z;K1V*U1yDZ^<8jdU+x%P&XOjD+&S^}`|T@uMkPrjS;|#s5%gZJ*vgXzbkVSAlVGf>C)2cyvVB|+ zDdE@?@!Q#^*;we7rHOHCb_tWAVfff^I6#_(s;$T!CUuI9W?pW7Y(C_J2gZEUWDAQX zI&bjH_DSv_ADa(1;io>|eE5Wna`#ozK8{tcwDG~`$y{JzqoorR{h-qPevsC?C`#`} zD;}=#kUDl;S_{d4F+!kXimNf6MHAaqq{CwJ=hoU0T*G$j>}*?;$!s4+IE1#~4Y39j zA&VLegjSysGh%aYK$6NEFu~R(o$XJhvl18qR6df#1Y0qb$Fo4{Mp)nyV*4%pNtz#R z1Rq8tr1fqoQ{*QNzBEXFX7vlSA36Y@54>5jwb})QQ{2Nbtvs-(wehUjBYlH$?Id&L zOF;LduEE@(`O4}ol>cO24jk#CPVxM~)d}EyLxpkkTdT7QKxX26xcUeHPgzT9==?r@ z7ei-O_AQz_8we$3OOQz5YR4`mb4N{x!{yANFqeL*(OfFW(GVU1d+A^QsRi~@2VQG1 zUFcCZ*P<$i(XMNQYIL-o-nBrE+v%m&JhZ&g*$fV25lvE~gM~K{W=U5wHNv{iEM?K7Bk7INTSf9_5D_ z=cnaJo*hj;QYL0Mh$m@dCM)qzR70aB%o+A$k)cq0Rnjw!jne>An;%5Q=r`B@BpUS^ zO#y1m^DWGCpHnZ!;BqB8Zw!4*k$Rbx+2bw!&fxbW-oXR-CbwQj7B0Nlkj(zR1v@#A zxbz`#Xm2M*t{9zdD&R4f79N%-Fr=-dQY$WBUuVYsE7+<+JgP zJRFgnb0r0?Lu?F_Sc2&I2YU@tumuO6@QkP*omJF*2Y~jDXuyy^F1f^NiNnOI$#eRd zi>d2-gkE;NRNmkr(ZmTStr~{O!N=98>E9rG0uPCW4E}p=x@?jA_boqOmXi?DOs5(- zxs~U#+y_+#anQQOFsW~KNOmY6=65X zUWAy??m4M@<6i$xXR?Fz%1sCi!m!}s2;B(W+Pj_hgj~{ue#Cn)8-Zj8fdz4}w=ujV z{mSj4uwc@*io$^58`F)>{vjSml%&=1=%al|^6 zCy#21&U>{@4b8mT%Lf5=!6STu2#uKrq9XV>w|X-(cw}d%IoEn$XBTluw3j#Z15S+% zU4RP>o)c^h=4vV8X~SdhQhl;E_4r~R$`>}QM7mdf%A^|dBp%hL>$_XY)>W$k-A+uZ zN?7Go5yoru_nJrLn871Vc+0~DKuIsV@-N)P+L*BhgL}R})J&e8?i*$g z2RmE>47ZWogw9Z$B71a9b2ZCDk#6Ez)5HD!2@*;*bCq?m>oU3KvuQk5m>ZVwDwigD zu8T9==Rq>LzAn{8zrsTwssH%vZKO5Q*CguR__*sP+MNNCMJU{N&pUfW?B7KXemE9r zb*>J#2FT%b5jmrfSLc*zR(}7i#0@#R+Pfe52_+IPB*jS?w%V?0Jg>Zujszj3$S7c8 zOZLqIm$-*A0eBiqK1A7v3mcEi*Pes}umt(wy~jT~VNY(x{6YF-_l1w$7x!n zQFLF3vNElHst4~=@KMxBKXzXL$(!64oH(mhZZ~yw)LN_{+CsV%pc{i%6lH)?|PFW?|xGqQu4w+JyM$HQwkT(q(Ch*hXPnnDJjaR zU7-;{4wv*vf%8fy`Dm1}elt6`kvHJL^2=xH99SF?-AUd%V(=Uzx1tLjSav3R!=v@# zu#2n!8xIES$P%d;hvM&mD8a!zKvSIpDPv#6CenIv?{Z6RteTC;@fv9spPW5&d3PVrDsXS)pO`SkV95(bHN`~B zj42HcE?7M>%UZ%ljA#p{S)_EZLpbcV?g*Ytq>EZqOX?C0!i0E+>3n1Mg3f;Tu&ZVn zBwT3fiQCZSer2I$3S%pciY;iR%vUx(%B{F!#DZ;Th>Ka6jLsoEqjkY|<$@!LHwe{G zg~hqiDI-5fp3Oj<>TC|qUFe>7EjmMTO@kCZ{!&EXK({z?&-! zeNag9axvehbwV?OpM33Tcn1G}@^nl7d389R4fsR;Atmgo{tTtQucdijt0(0Noif~^&d%Dk#huqg}rrmcVt9*=xxXisPfwyI|3NMso2@t5L z_f5vjPmERm*JPRg)bY9V5d6nX-x4T4Hu>O2CBL)r$QK()%ZgvX=>B`^n-ibdG9Vw9I&kg(11w5td@0chW z@~b5--WntsDS}~IB87ChTuLKu^qi^H1|lo4qrsv`9Re1ZOTm201ZIbO`VCL_z*tV> zZW?5b74j02?6^!W0%2SO#P%ac1LC68uO6vutc6nhk=IRgATZ_P5tw`>co_I-29-I`C1S`E>?HG8 zE!R7##OmI;4$&yC%9%4?J-Z6^?sgCILYBhlTTGjroV~Jvv?&cQw!VsdQGlJR7UuPg zt5IEK3hMj)*Z`uAS0ae=wyD0B*H?Fo0UdyhLi2Vt=sO~i=2R@y^GgKPgGeg|K$xV~ zP$j;X55O%SApv9{JK>uK$UF?$x&jVSLIlbBWP)VTdvfUsBUYhR@YbYR*WnvoDq?{% z30dhIQVpkz)TqfAcs9Pb(=RV@-K<6@4*P_ABy_gzK5*{n>Jje0z$OW)mwv$+Bz;L} zB7-zz33Ch4qy8jrw+?;rY?7n7kh-$-Fd@kJB4EfqcF_gdX{uE#=5=hLwWK$KBy> zBkUDX1M$_b7D&ZGJl0OPCeJd|U=zjvn48`eIoIQij^2DEHaz4>+>-=6+0+CPB%BP< z7k<@pXW_0FAdk&{wOE>1Ep;fePi^g54oOuT=DZe@O=+s`wiv{f2<58&U#63mcUVw4 zm=y$8kl?&Gqv8^b#z}vH1&@lYzQ|&@ntiGaMtfu*O2<7bk*-x8_rfXCz_8mE*6rXk zhXcG{@6J?hb)#LNN+G|+Euv9D9;FLYWlFdQUV=qRq9e;xMk#%XW_iW2$9iwpVXr7+0}mwfL*O1=-JdguPs5v*TUPGT=`8wB zI9kkrI8=6?u~fTyS69)Jvf*g$ir+J9CN<4JJ{IaTM~E< z^Fa*0Og9AN?}U*1M{VQcMM*jPV2G!5us^}=2<*=Wo7NU|vPBG2nD42(%s&BgkHU`I zyufG(32PnyDyJg$sA(;s9E&KwK#FTf(iDpe!X-JeHi{J6oR2wrt5|b^5I5)Mky~{o zfPET5~9($EafyB%Z(PZ;0HT$vm>ofR|>f=C4pSgT>3b;X7T_icE6cAnZaTaeZ0|Y*;~Hm z#g;X#w8_4e)X56x(kFuih1l_^9E9yp)jW$KFnxGF6-3dEt0-FNmb+_gCWSSwbg&O4 z5v-(v0vfOqG!p0ovRPFwv>0XEK3E62nL^tB=89(3dWL zbI(0&pXo}}m!u6gx%j+|T9)R-?Y(58w)Qz&rq78v_d0ganzg47QMpxb;RQunC< z_F^|e`)>uflR^>NeJX&nB^kl9k3|KW{|Ieg%=F!OilG}p^(4dDZhEUFyO&PvQ0v(V zkFpx;U$853;;KCP8ati{=|GzT^;fE&lR`ORM@ zP4<@sizZrS6s&o{)LLk?)|`dYV7k$Y&1=ZaI12i>>nCxydjn$=4^G4JX*O)w{|3-T z_m6@i1S^3iSgGMknUd&kir_D|3F&f9%@0aw_QL<2q z;F3LEQX2{`;rS}oZ-j8fK`Y7Yw|*hlah!LIFlDV8 zTwp6+-?Q<)JOzH&*{Gz<;J59s*Fo{+-o-4`2?-2fdZe@1(GT|BtKxGr*s&r$;6$w8GzB{X3}8 zKpB(Y3jI5){|BHyUynYI%lJpD{|`XVHG(c+oByx(eJiNnFbQd24*lwV|4Q!%3EsE> zxJ}20lX^e2()$#leL#epG!cM`_|q%B&(1|0gsMV+ex>&XLVvD))crn1l)|=FdS9Fi zOWCKePp|a8G^ZC)#wqkquk<=|pyTUV3jNGV?=+!(kctr_=35mQNx0es_f1B+G|=BV zC{T+hbsm@th!U{JlTA`}5hDxG+Cglp?7k&%|82rHF74wo2W{xGLPIjM?4y>hPa&qjr-eb)vE5 z3B=gM(K`EHJ7zC0$4ma}+eqbS9Aj2L8>N7y@yRdaAvdzN3{8*V;acF{ts8eQzkIEK zyivEu||{?BA!JE zT?+D`mWG#PDH!L2QCtpeuEfYX#2b$GA6!gMq$v!3@tUKzK#%<}ydBY|83$Dn3xbTn_j{5Oa z+{gqG28i#4^KSz;0v81W`?9?oG``)uRbxuPM%e&x`(8Fq-R;>21)9jXKtg!}1o2B* zeYdEYF*B;0OcgZQCAY$ci=liRBu#p72O^hU$m+%masp;m?FP?FCXkrxQIa{wY0!{} z^phGiAwt9oCN1G5v19F~sR>~kO{EEUO$IegX=(}clv=VmOJOm{ZYswEi;0jNY+<4k zlFiX>LK5dqQKX-#LxSL(jrHL;)y?NJ3^4zeW8p@VI`L?h@YrMq9QM1YkBLt8H)JOV zjw>~qq*+)s;e4$?M6%N&Z8&2~>OoUa7-W)9QsA2UY8a5ko&?6>j+sWmp<)cou^P~r z3c$D-@E-R5-2;iB;U>O|&3k;h^@tDa2?6ZRhkf_PTjPQ6iny3T5c^?6!9q;0AH1*e zG4Ji(Lyv4pc0$4UWVV-9N5WtpV~c@I>+B*ka&=GPnY`GLOcqI03^t4q7sC_12zCdc z)&gODh}5|oOzgs+3rDtQio3qPxfGL5`okvS6EQLMuyO@ic+aEu z1lcw%nQbI&b@D5}4kdVKgBy(=NCRbxpbLX^^iCB(X_=VDN+!c>KaaJ8U1>q94neGk z-~x%FiaW~!40x_P$@4T+wQ0GuY8hu`TIQ3UKm zGg`>%Tk0U*g(d#5F|>OsrNOaPWPOpL(pN2kZE=^sSBG z8zv&yO(GEV#rjZ~c7$kNHVx;GW75K52{#kr2BRd+?rxpqMHq}j;V(gyP7S3c*&4v+ zQn8^QG!H#HAkQCvX3)sg2TuT8q20K5 z8dplEThTs!s(IaI%_~i^ZzW-}!UpQh@%+y%>ad~T^WMHK9|TZ&i(=rS0^9{v?)E>= z%m4N(m)EYXRUG`YAz?0^kAGFs;93())BL#_1oKm&YIrMD^PHq6bUxDWaxPNA@#n#A zDKH1G(dr<5^Yr)RuFS<_(cc<%bASVr5S%`VxMQr*_luK~a+mBIb~tbsIo`$+M^_72 zj*6#@!;NpYA&Tzvk z#Hp)SefEz_K%=wlFd3$@c6|A?E{+G1u9&4NlK}I>e^|4$R@e~`HVf&ceJKnZNfA`Q z_`3jWQf;(WLvew`?e|*Gz7(KocT~Xmy8z4Na~x~-v8X_1kGBCrnDil;1I(lYZWNgM z8E$0J5WrJg3AS@&0f19-x3<{cOG&+neaIqzyco-u$44o6NDLzEa5Z?Sp5@Ivqg=6& ztJS6{6mR0}Xv%p^R`ym*X=fo%2g}h?jGZE#1oJ$`7UPiOd=Gd!*&v&lH?b^*Y~aJH z5fbblP<0zbMhzAtXfpGeS^WclY4X?z^JktHshR0Gs(UJ~Sr-=Ga1h*M`w)Va@nL$>WVM z&#(97hZuWp6PR4{YsN`q@cR)mM-?SEx63R!=^ggOB%#C41__bx=z__XzDC%^b*Vpd z!5Oe8A!+*DcV#Tx2SwDh%=-QJIns^ncIuzuz&3JrCT3N#%VB0?u76d)WKB&+<~qGs zTTFW|l?=1oBB@QI>-$%;&KRXjjijb?Q7A@}VBVjsFU`d84?4KkOXcKZRR^`o4> z)St}Rx+JrM@>Gz|(b&I)Cw5vtxihOcL>s?5D?_{A+;geripxGrx$kYTjb#DO>g$|_ z$MwOTzS+GQi_|9%zJzs>D+;bh+IUAA1wn0((afiH{?Kyv5Pe5FQo z#z~0-3NIwV7ImC=2O6deI2uY49SdyMAZP1JkpmOQ7yG;(qX{~(GPo%Q71mg_pMb41d-=LGQF8_sNvUNF#X^4>WKW9AZ*VMbC*Ham-)gfX89!xZ)i^AUD*R_a6{ zt2pNX6m}PI1-+rvg*vr2X=<-BufapuHCTa|*WzX+3#)ky&0Zm{PASliN&lw(?y={g>`!$fN{Bf#QG&|gmY9mN-eb%~iK2Nj zlwHJ-zKHsdbu5iR`b+q5`MxOS{il-DzHBaSJs^n5g7g3c4wE*Vr4)VqeTP`Ok> zo;Oy^4GQmh_Ph@(!GsS3Wj?+@ICyk0!h43@o7e8PV)`b%daVS2F1+U?7vAreqGZ1b znXy){tZpJN)=4WfV|)H=mcnnX{wm;qNZ{?NQ47Db`o~fDBU0!CM6~$dT>Voh4qc2F zXj=5|ul^YneNJjNEFFdX^Q(U$b-?6~7XIbc|1`A__XREb&DFn#q92tOvYSgS|L<1+ z2b2dQJpvKMpGnJpYxVD<>?ftJ+g|MYMdAM8>OTV94+vbIDDEGx{w_+yH;(Q|3yA!C zy&qw=vhNc_^au#}d!JnC{WuH0Ukbvtv=)74rT2Ljg#o1dX)XOJ&BGSiBg+(r#A}jD z?J2?P6T=~GT9-&;wJZr9sR?ZQg$IbY! zzta0(=Aq5l`hQ*N{T6{g+kn<(H~j6D-rt@F>e&A8tn~i3<}MV=;P0*U{y{Tvu`GUP zrS}gB{HePBhGo)wF~CS_!v?rN%*=-Mbhq9K(88&l1LankKrLV)fzkCY{||iu}qUXqMfW;MvEG8Qv;OkdwoM@evpj>Cp}+htn$w zqFS4W&F(&*jEuGA{m2Hu8PexPxV!kbb{OwB50BP|!$`>u&~>yO0k6&cne*w=b@^TCM-e zy~|hDj;6EW?wl%6wg%(DC{gJ;e_tLQEUFkg$3{Y$tp3&OSMJugG~Ia=;n!YyZ650J zXr12HX}llZIhoz8#Lvm@;(4gtNpJ0-d{iJn=V=3Gq&fZDzz1t0mD%^X`;3j z2%maNk~*~FiUTf7?++{eYn z;}xi+G$ibl#%=_;U;x@5GfS0}BHqYQOuUlF3wBG0Cz@{W2%e+kWOv}rBhGz;!|{wa z&8emZu)H+buq1x5yWQ6HEqPAkG`pE$iy*;Em2o<>+NbW-HHHH}xZu&wXk$m6O*4$l zFAh@d%?3=cN(=U&wLicdZ5)mV2d(ue(fGO^^C)g0nke!qw-1JA&b{z6XJI(&v_bg3{6GK~0Qvyv10Z}mWyY>lo4{wzpFR7WROhe0{Brf} zqet)pUhB1rvCieSSMFTC7Eshde@&VJ^w;R=V$fe}*Fc{OV>*8p|M1ZGSqFVVai6=8 zLtm(cem+7!pF=-i3;jZb<}1q9?{hD}pv!3rchybaL}X6ZtB6u(hHVQ6dB&6)B}>}J zj2WBVglO%+JK*SnIPzqxVt(4eBp8N4^KgM@OA}w2ydgt=W2=M6;;{NrleX! zxviO8_oItW{*{H1#V~N@Ipym|vNd6gvWX`LW;AMKE@ogeZ!}l0Nzbtxx{R>pT~XO! z!+jBk8sc>uL*wQ}Z>Aos4QC4iH;dVf;hM?#NENvftx0l7_cRa$Kc5c4D)4yNK-5dN zXk|9A=^^HKJR9wgdC9*uJQyOsvAOUBmMy7+Wi>ZWyj=YA*_he9_o=?)*<^7oafcY@ zsd1`?Z1@-wc4$!p2d%5u)*O%D3|Xs@pqg(um&oLK+!kJw8KyXAwEars0m*h+te2QR zd9b&K_nncB4!Q5*=bZsGq(Nv;4lmG_wO*+OtyMd4nR*U2g2YK8gbl`?iDm`H}3nJq@=(Cj;Mc7Qbj);pNI_L*OPGCt&9 zeCb?%NgpC9VW)}KIB0R$X3=(RsWsR*m`w2-VY2F1ys-njC^U-JoylbP{8j9NX&bx? zwe!&sZ%4!C0$mV$Y48FM*r-uMIff9J|apZ77ad{*82L@+7vf%c`$M~TG{ST zjQs2AV+=osoY7}n8#{QR6A3%eOAd)@I#jON05qW<6HH*Y$A{BkO&a8uB;qp+-Il!e z5Y>C3EmF7WFoN=}XO}o(tzFn~syIc%39~YMlLl(c()Ft^%6rLH)vxG=$coh@lRLIglJyu{(mANZD11ASV7@1}Y-DmS~ z4EtLoVr20y8ahhlI4xm{#-=Q@d;FX3Vhu23&JIM&jBjtGK17UTp0t}-zRE7igm%u# zydsGl=Qvui^U=~*rLmtLoMVy=i#>MG@PA7wCtHB?zsmH@xeI9ft+!#O5&@CUDI(}N zyIsShPT*{p;rzS%hcFwm?+q(_Kj1VvZ;cQ7lmqnazyErgOobDxb5TV3K9wa8np>a3 zYQ|me>>1gX2MPc$NXKEtJ zx}PCJNwh`>D^9e&%TNu|Y%)W5n@C8+5FPGzQojr)icU~Y#v{h z>n6VQiHqwajv-Bn9&m2kw$WAC+^@};<8;IkrV$3}AnR*4DHl-((?TDsuCJ3+x9xcX z=bIbOR3ql98EEIIRuxIlsoFZDIPek-=iXJE*VL(DakG#J8^u4h!d8HGg`aW73Un$ zz*}FPZT?d%>YI2*5UR#zf3i0|y2Las)w!o)TbX;&bmxi&UI?|Oa-}?X`q>xJWLyPk zAhR8El`=kNk*W$a(SYLqG=k1mrl;(z%?nurv!9LnV(UfNb$A-Wd_o0CWVE%xA90rg%qQW3Tq{ggI12VBrMuN|p9FXz_zFHto$L-?Au^k~5}yr%9Y7 zijCJWb1nqCR~BX3Y>@MXWSDw)-=7Ib&Ox|xmzDRTN{VhpNS3@vwDmHPCGnAK4vqfN zGCW+kuu^isf;TJ6`4?fj?oJ+pj+)k6Zzm;7s{1X}1gm{Dq>m?sp$h7`B;y*MW}5{x z9{@Hs%M~n+ueqjDCKABJ`Ct=Csltsii9&^EbWn4^zr49gldRsdU(Y-=$eVLlvm6iI zYP}1|Yov_wGAwF4CP2*Ms(dp@ehO<2&(&+N0zck-G?T8LLURNnJWW&{;$Kfp?!jqg z8L@{Zx!0`?4<3#-con5KpjHP6PAP`DaxkqHauojxxmXd}%Zdne?Q|>o-emG2eLbdl z0LpslK+3y=5&0gUu+~|lNi?u*u4Ev9@vY{HsvO4x)o_flwJfI|W^oi?Jtry46$hYZ zMhpYcq1X!E#3DJEj<$}J=_VT+hx>!QjUybyHir){@r}PREkn?I>{DfyTL_$n^@h$( z!*3mq_6@YP4Ofoxn^}-kD>W!b@KqZl^BuJThcKE1`jf3KNc>CZ>^M>y%C5%IiN&~Sp4M8(pjL#8544=1dW#wPAW<~xS*|<>e9o4Zn(e_M&|~-Jv$zMN zb+O_>(4|2tIMdqk`b>7^hXYu_2J7%fmfqqRyglMI+)2K%dorrCNE2fhYmjRRW$4fN z2-XL97r=768SVwA{*E8AcFJr&JHeYTQaxF`?m)i7teF&)z#S(4<)vc1@D>Fsp(+@v)j5ZT2QUU>)52s9u+>uY z;@9;dD7P7(Smj!+9xIC_M1iVIvOb(W8o~m5R`Al;$W_i^K&9kMwmRI@vnUJ_N&rr9 zJKP6+FbO2jFw&Af9eihPb8xVU-S*)~mQEELpKA`w9`AN?b>&ntHLi93Z0wrLfW%(q zGT}*#F=FH`&}{m_kFZXlJ&AEfye$!myPWk8$%qR{{Uinplpnrv7Q4@r7$+QPL}LPK zy~TvV@zDp*#MLeINsQKGrJ*;(x5TY4qFwdWzUm145 zJzQ=y5z!kco(@(q9$D=*N3s5JuJqb5*CxZ|C!!FNUP)Elu1S>k5omfCNa|m`?=J#&XSa8K^TrZ_++r81nY%5&c7+9RF0;SnAG3ax>j(b1`24tH>Ht(@bkSfXUrL!BMz za@L891y9b(uu0l)kM_fu_zta6qo6LkO4=^Ixd@oU5qa4c$Adq(YZBt*3Jk0;+{SaI zIu4lmSfZf3h;b*T?1<;3Q1X0)0dVikVEtgU3CEI_X!F$L_J-FiN^=NYN zz%^4nywFXPd!}Rmbi@cp1sK_zhGe!JQk&KaqKeQd4u>Xa7RqXG2=MXZ7$Oz%NaE3X zzfEbzcP(IejfhLi!lS>q3{UrLO;w^DsGID#Bt&ejumxd}@lkHR>d9dkheDY0mFDDH zOz-@<*N!VN$n9p=`MG7578^F01(m7We?Cgm{EBORZ8)oYZaVMX>v``>U#Ys@S74Uu zeOU?gtM5@S9$)Q1l0>Doq;V)Y)CV@0 zq8m0Z>VObA+KiCAr8*KW4{?X#MwlWSme?-pfSCtuS8HsibXM{FkE? zHK8|GMrOV760Q_PHHcds2ry{4U8j9!+B?V!Ygpj%x^v3;Hdu4KqQ~aGla95i=UffuSl6GMM{S z$vTI_<Pjti{@sc9%SKE&07$@yIUq-a~i(|e<>Aa3c?04+-$CSbSVQS+qL zK1s<3tNC;T7dDW?Nu3}f{tXaDG(JLR3SP7K=x3XLi|evA@0Hi5ff5H;NcPa;Ll|e^ z3m&EJx;itY){yJ~&tK!*5K}V851P_A{iNU_$wJEFwnh&lem0?sP2t{>w}(FP`F=!` z9fDQ1lQ3RTqB=qa5wb=~waQ!;K-C$*S z`SD1VicgFDq_vOT^ zOzttlo)bCqTrqx3Mvl4hTu5pOXGZF)AyC|yIvJAFEph5{!d`Px725Ts0A@=Ta_r6! zLUzy2@HB&MXUa8H#s(us)w&S3P;+mi!NR+?!DA7Dr)G6k<@Cjv;Ub9dG+Cqq{~*qp zvT%mW)lL`%h4dQ??BE2O`Wxl0e1)y~;b;>Pq!oO&Ewnnplg%<`2>yCuFWGBg-E9Xl zA;rO4Z=0o;rT1ge>(RJCxfX|49w4w3gQr)n97i&$=x?fhS5oQ@FoA%@H>V34;B zjIE|^f&V2@aR`PU#K}+iOECip}Xu z$b_{vLna@Ww}f2WzRMVpwc(yzkKLfvC%2ggfGZ*Rdm-E_=o09%5KaO<71;DhTQj6F zE+zJGJ%<~W_UU%_jmc=Q69#$8^fpR$7!jBt1+>KfA$wLZ)El9NYBltB^Giz5@4k-< z6KRo32oDRJq;syh%4keMM?)IX-lcSN@x(NV92Lm!nGY^CC7)mdl%tD zDh$q9;%0L+M4qZnz)bgZUOkVGPF0YEY6*)PCUg-47dRAVst%Nnz2P>P8uymLxoUc< zTS0brX9P#6*rVw_@_5PWq=*Pzi5M$YUqb(2H;Z+HBmkdFaOM2EAWfpRTM}vMBxZd2 z_Hgh3QKamaA1G!EIgVwd>1@ODE)J27Uu}A8G5XFnV;sD>494p4>o5vbcXtuW&B-CJ z{NZ@jJG55 zdVN?r23CoEv~YXYNvkB@2mta$RrE_uxFe|4X}Xf!$abiRs#{6^1?2UrS*07HuC5>1 z?X$YRps8-A5aqSAqEx@}ZbZ&=;WTY$%D^~s$V(s7q4JW;riM&y*>O%73Tbv21{HEY zrZcR_`_T;U&qOI_Vv)1K9Rz|hncn_?_TD{6&Lp`HyTMsud1*2zzRBb9`W7T-um?0= zx3|ZoVDB!lFZT8>4B&2g!mV44nVvx}W~PVTGr-O+S7tC6lw?t~q*%$MY*A!Tmcx?8 zhiTKYEXj5_^oUT%mSj4p;9s(W;RuVCAAk6va9H;5mz7zSRbPEy_W(HFlDvt##Y}fr zR#sMKR#sM4)|t$85-R4C9gH%+#@umETomzx!_B6NQi>zj{ZOD3m~Z2OJs1JpfaV#u zR4wgWrYq9Rk$DDB32{oRXi5b2AGrP7eU_8uxyZ)4Rb|uysYrzg>9dRV!W5t#%~PW4 z49}o1<}|ZQ$B)^fe=t708=R!nGQ^_{jv3;|eMVVbr46GUy&96~f(AeA?7?m~uLjJ2 z<+KL}UvSD8p#UJRnWBaVPjwXvPF&d}JuE26u-{wl8m z^-!&~7cO|U>9eHIR0-hUgno5HJu zOf#raw5@1a;bN##m2>Ad2>G_PZEqlvdw7>xAUae~QztNZGH_BuVY8T1oS9usiU~~j z)l$K76ZhVe@4f#dlKYrjQf`PttREr$#w|*Of-n^{x5b9JGSmJsi^NgxU6i}-q~Z>>@UaFH->2`{{bf)2FI);N(tus}t7 zV#&rUvO(XF3UM2}R`w=N2ZSK}VI3u$oT50aGRQ;4s{0r|o)V&VN?a6gdKDRB?`GtP z^KVk(P#tmb-OU(DSSWKria=a8ggkb$d=RI@t}Jb5AbPnF0bqj7B?K(oo*t)T4Q%Kz zU9;UdwaFk-7!d>D>Q4wwpv>*meQ@ub07+fQ-Y2i%o(*jbTShihe6o&g?{q((W98bkGaoDphaaQZ53oL!uB`9<8SyD$YZ{OK^$&e{>+67{R_SGLDKqc#cvZ0 zvJKL(2Xja_aJ_41fDhEP9q{+ ziBz?lhP@KfNl`ti@2>H@WC^G<&Y!`tL)iEfMv`~Oc+moE4~fE1c`Sq!4o0=PtEaHZ z?mV-VnM|vZ4Ss#=;;w_LYjd2{3~`%U=3?4F?3+Da#F?6hId~5KEvkkWZ?QY3+ zDxa6DtV9`33V8G^z6jH!krR)w48pD`0?IG0#>velLKiJ0{p-ou21NX5a<)SrX_905 zW@D{tmtzr&_ujX}&bW4QOo&X@O13I>LQ=~T)W>3EMMvrWh=kfQ#jA2yrkX3NN?B;w z_dZLYrmM%KXD!S#N=b^GSe^~#PRTe>XbHoq1ZuxY;LA9F1}yBB^XDqG#XkC#FDV0w zTBt@gEPhLyjP*5F2!Vo03eX7q6LJG!376`OKqOmYubq_9*G$8(13H+GMyotZrtOmV z6k-sp*`tYsJkE=P6g)46K9ak8=7|sZ*w`n{0V|^z#nVfJ@0AD0KHdsWZ#q0Kg!jl^ z!ecgPT0zS*Hf?ru@P*E1r3<6Ywgz{XHuHu{n=J+p(CkyKL^iz-ZTQ23A4S9OZf%%V zkkmGRXz*ib({F8Kg|M=`1a14{gP%v+r(4^Whw7S7A^N2#esS)&;1_%E|{yFDy@8g2MBr-t9khV3TW zmKAOAu~Wlu?`}}MJN6x?hM!=AZ)szQKGFBh0wzz7b%6fRNAdjFD#Qw4J2R_wXg+vb zT0NYGNz+HutYtLU%H}G~9nx(zKbAu#JrGLTaXQ;1kdMLY3!ZlCP%c0WJn4WQcGZ#| zPiX3wP+7NOCv7CQOB$_UT?u!z;tOziD(-Z8ZE7N^YySQpd?p^_;ib4=?bTk2yBfal z-Mot=j+W=*()aSmWS^d>6@2yoDp<|p1gm={H2<*OOf6n5#$j`MtwNT29 z@bQwy+tYVY0)`iC;ais|UgDRp>X&syDTS;uh|>984Fv)rxULf3OA`hT@j(Ms9T#gP zdd|kj(4-_zczBHy{)9bzrV}jvlzp7|@iUK16W#L+NP6=qBn4TLYdiL88iHO(i14jX zbW_p~7OmMp24*8Al13k$7f=@mOZD#^3{EWZcv*kUh`$#ioa-&b=+WeorOK z0Js{*Oao;B;a#M=7nhs1rrX=BH|B-Fl(2MQO6`RVmF@n9+DJd(!1bRjcIEP9?T_;r5|5W%dlaS?-_t+ zRK`DWggk$}8z8W5D;e89CFkevPtPUyaW;-Peg_ch`^CwYw0YF=1mnZwKD?D6;Mt>E z>vFJ;2w(n|mV8j}5*u?tg9tXBk)L9>j{P-v!#KBy63!@K5jjyRi3{h=zh;)<@3Jq}b z=uULh^pdcQV&aSZS~RDQTFIX*yulW2J^P`xPymUhAs7cTuDTfu!E6u+EHs(8Hv_ws zu{#DoeMeeYLY|h2k{1XsNcXMc;8uB3Dp+vhe9q%2U(N8}sd!2N$pthmM&%DS^59fU z%ng+Y$&RazVF_$$ktdRb!GIW{8aOxpUNAvsa|BZi}q&NCd}inIOxN zpO!aY@g*q>z_kfeUFf^Tit?ScOV#?l>CJ>HlkTi>GI=5`&(*&yrJxS=_~l{aX6|@F zLiB^ojXJYLOyUB@Lk&^677jLpxRjLj5XfCYrcCtv)?>J}gF8~;7@jwhnmIY_Ba4z( zTK6T=%lZu4d`AOWIb2I_dDGtrKoc*2)(xM#re|2-px(ZQLn%r0fzP{mE2z*oNmY3~ z5Rd{b#En$R7<;$hd;hJ(p`cvWuj7J@L;g;IXd+xm8x7xznpl_8Wjfih;8zsW3QA*U zxyC>MyoIC*q`f|e^`KoL%N8ajYBgN35z$eue{t))fqEG@QO7Ao@DrRJ#`31cQeaVO z-o;v$4!K>7Pj^(@b<)@4V{^1R2_&9>jK7=(Q@VzgJX}f_7j*6pd<%0AR?6h`u7av6 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 literal 0 HcmV?d00001 diff --git a/docs/.doctrees/index.doctree b/docs/.doctrees/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..35bd7a29f8d7532fc9a5c100b6bd8dea5bf0b390 GIT binary patch literal 8045 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 T7a(#-tJ)St(k$qtok{oq*`R`= literal 0 HcmV?d00001 diff --git a/docs/.doctrees/modules.doctree b/docs/.doctrees/modules.doctree new file mode 100644 index 0000000000000000000000000000000000000000..582d8f133aa1b46ee3976fe5537b0ad8cde773d0 GIT binary patch literal 2817 zcmZuzO=}!C7s0+V^mw+q?qeT~e-6BO_p{GQ_X48IrnJqo?X4>Cs4tgQ09_)K{} zL>fj?XR2g;ArTp}7QfKY&*_Ts!i#vmkE+q4YBOrQRAwHpLsv+~fQsudZcev?zAp1Q zx17cEoiMCG;EYyl=nes{n|Mm`o%lhVh?gkDKB_xI=frkWVcO(=dSz)*a2x4%p6UGQ zO;?f~G@rL7w$g2yg7ZzSw)Qqyq?`IByF=LBtGivrheq9wZ99+_gW_d);4Rfo(Nr%| zShKX;)fnt}Wz(9FbZaPnip6cSYtdwMgLbZ+?&O4P=`R^_Yw-j zW?5Q=)fhb?i6dzjp>$G1*D)L~U`89yw>Ce9ahebS1X(SN&Ev-~ae!k%fcP|b91K3H zC0y}JLawA2WW!VVYYsHTy$B=A3u8S|{4Ga0cf(Ln)h;{Xh_587=&3K=MyV4zjL*v@ z+)b{i)uwV~L=eDS#6& zKyI0jVOm#y%SxxR62r-zojWGPhcKy)-UP5Y`uO(7os;1(B>><#f%+&U6vJ3iy)5aH zqudPZT@W_hw>&eJ5wIJuftxfOEJD?FgkA3$Y!F2FVYvBIBqLqa-FO(^!orK34N-U=l8-+@4A97nKi8gPHKTg0q3Ab5Mw- z$=wep0Ax;DX0{0sS0sd7heNm4p00?HOQG-sc=we_xF5Nkf@Ob|ptM7w?pN!2NtDTG zeOZK)Oi;vw#@A#+m8%ls^krGVMS3+h5vH)-frQ6Dug6kt^?>VbA0_PBnV-U*>! zj}mYfNR*mMaKjT%?UG|O;f-*FpnxooR}aQHuE;dX!|^R?{c?a9))wueo8~DV9gz2u zu>KaW#VZ#EN#NH7B77Ic>uV>T;QuQza$&sPtLpSPljwMI4~w-VQF5bKhq*1O^$

  • ' + , minLength: 1 + } + + $.fn.typeahead.Constructor = Typeahead + + + /* TYPEAHEAD NO CONFLICT + * =================== */ + + $.fn.typeahead.noConflict = function () { + $.fn.typeahead = old + return this + } + + + /* TYPEAHEAD DATA-API + * ================== */ + + $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { + var $this = $(this) + if ($this.data('typeahead')) return + $this.typeahead($this.data()) + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-affix.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#affix + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* AFFIX CLASS DEFINITION + * ====================== */ + + var Affix = function (element, options) { + this.options = $.extend({}, $.fn.affix.defaults, options) + this.$window = $(window) + .on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this)) + this.$element = $(element) + this.checkPosition() + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var scrollHeight = $(document).height() + , scrollTop = this.$window.scrollTop() + , position = this.$element.offset() + , offset = this.options.offset + , offsetBottom = offset.bottom + , offsetTop = offset.top + , reset = 'affix affix-top affix-bottom' + , affix + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top() + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() + + affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? + false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? + 'bottom' : offsetTop != null && scrollTop <= offsetTop ? + 'top' : false + + if (this.affixed === affix) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? position.top - scrollTop : null + + this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) + } + + + /* AFFIX PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.affix + + $.fn.affix = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('affix') + , options = typeof option == 'object' && option + if (!data) $this.data('affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.affix.Constructor = Affix + + $.fn.affix.defaults = { + offset: 0 + } + + + /* AFFIX NO CONFLICT + * ================= */ + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + /* AFFIX DATA-API + * ============== */ + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + , data = $spy.data() + + data.offset = data.offset || {} + + data.offsetBottom && (data.offset.bottom = data.offsetBottom) + data.offsetTop && (data.offset.top = data.offsetTop) + + $spy.affix(data) + }) + }) + + +}(window.$jqTheme || window.jQuery); diff --git a/docs/_static/bootstrap-2.3.2/js/bootstrap.min.js b/docs/_static/bootstrap-2.3.2/js/bootstrap.min.js new file mode 100644 index 00000000..3a3394bd --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/js/bootstrap.min.js @@ -0,0 +1,6 @@ +/** +* Bootstrap.js v2.3.2 by @fat & @mdo +* Copyright 2012 Twitter, Inc. +* http://www.apache.org/licenses/LICENSE-2.0.txt +*/ +!function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.$jqTheme||window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.$jqTheme||window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.$jqTheme||window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.$jqTheme||window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.$jqTheme||window.jQuery),!function(e){"use strict";function r(){e(".dropdown-backdrop").remove(),e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||("ontouchstart"in document.documentElement&&e('
  • f4Otp(%@jzNcR4@% E9|wJBDF6Tf literal 0 HcmV?d00001 diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..ebfb3665 --- /dev/null +++ b/docs/README.md @@ -0,0 +1 @@ +# documentation diff --git a/docs/_modules/dragonfly_energy/cli/translate.html b/docs/_modules/dragonfly_energy/cli/translate.html new file mode 100644 index 00000000..f2b461ee --- /dev/null +++ b/docs/_modules/dragonfly_energy/cli/translate.html @@ -0,0 +1,2079 @@ + + + + + + + dragonfly_energy.cli.translate — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.cli.translate

    +"""dragonfly energy translation commands."""
    +import click
    +import sys
    +import os
    +import logging
    +import json
    +import shutil
    +
    +from ladybug.futil import preparedir
    +from ladybug.commandutil import process_content_to_output
    +from ladybug.epw import EPW
    +from honeybee.config import folders as hb_folders
    +from honeybee_energy.simulation.parameter import SimulationParameter
    +from honeybee_energy.run import to_openstudio_osw, to_gbxml_osw, to_sdd_osw, run_osw, \
    +    add_gbxml_space_boundaries, set_gbxml_floor_types, trace_compatible_model_json, \
    +    _parse_os_cli_failure
    +from honeybee_energy.writer import energyplus_idf_version
    +from honeybee_energy.config import folders
    +from dragonfly.model import Model
    +
    +
    +_logger = logging.getLogger(__name__)
    +
    +
    +@click.group(help='Commands for translating Dragonfly JSON files to/from OSM/IDF.')
    +def translate():
    +    pass
    +
    +
    +@translate.command('model-to-osm')
    +@click.argument('model-file', type=click.Path(
    +    exists=True, file_okay=True, dir_okay=False, resolve_path=True))
    +@click.option('--sim-par-json', '-sp', help='Full path to a honeybee energy '
    +              'SimulationParameter JSON that describes all of the settings for '
    +              'the simulation. If None default parameters will be generated.',
    +              default=None, show_default=True,
    +              type=click.Path(exists=True, file_okay=True, dir_okay=False,
    +                              resolve_path=True))
    +@click.option('--epw-file', '-epw', help='Full path to an EPW file to be associated '
    +              'with the exported OSM. This is typically not necessary but may be '
    +              'used when a sim-par-json is specified that requests a HVAC sizing '
    +              'calculation to be run as part of the translation process but no design '
    +              'days are inside this simulation parameter.',
    +              default=None, show_default=True,
    +              type=click.Path(exists=True, file_okay=True, dir_okay=False,
    +                              resolve_path=True))
    +@click.option('--multiplier/--full-geometry', ' /-fg', help='Flag to note if the '
    +              'multipliers on each Building story will be passed along to the '
    +              'generated Honeybee Room objects or if full geometry objects should be '
    +              'written for each story in the building.', default=True, show_default=True)
    +@click.option('--no-plenum/--plenum', ' /-p', help='Flag to indicate whether '
    +              'ceiling/floor plenums should be auto-generated for the Rooms.',
    +              default=True, show_default=True)
    +@click.option('--no-ceil-adjacency/--ceil-adjacency', ' /-a', help='Flag to indicate '
    +              'whether adjacencies should be solved between interior stories when '
    +              'Room2Ds perfectly match one another in their floor plate. This ensures '
    +              'that Surface boundary conditions are used instead of Adiabatic ones. '
    +              'Note that this input has no effect when the object-per-model is Story.',
    +              default=True, show_default=True)
    +@click.option('--folder', '-f', help='Folder on this computer, into which the '
    +              'working files, OSM and IDF files will be written. If None, the '
    +              'files will be output in the same location as the model_json.',
    +              default=None, show_default=True,
    +              type=click.Path(file_okay=False, dir_okay=True, resolve_path=True))
    +@click.option('--osm-file', '-osm', help='Optional file where the OSM will be copied '
    +              'after it is translated in the folder. If None, the file will not '
    +              'be copied.', type=str, default=None, show_default=True)
    +@click.option('--idf-file', '-idf', help='Optional file where the IDF will be copied '
    +              'after it is translated in the folder. If None, the file will not '
    +              'be copied.', type=str, default=None, show_default=True)
    +@click.option('--geometry-ids/--geometry-names', ' /-gn', help='Flag to note whether a '
    +              'cleaned version of all geometry display names should be used instead '
    +              'of identifiers when translating the Model to OSM and IDF. '
    +              'Using this flag will affect all Rooms, Faces, Apertures, '
    +              'Doors, and Shades. It will generally result in more read-able names '
    +              'in the OSM and IDF but this means that it will not be easy to map '
    +              'the EnergyPlus results back to the original Honeybee Model. Cases '
    +              'of duplicate IDs resulting from non-unique names will be resolved '
    +              'by adding integers to the ends of the new IDs that are derived from '
    +              'the name.', default=True, show_default=True)
    +@click.option('--resource-ids/--resource-names', ' /-rn', help='Flag to note whether a '
    +              'cleaned version of all resource display names should be used instead '
    +              'of identifiers when translating the Model to OSM and IDF. '
    +              'Using this flag will affect all Materials, Constructions, '
    +              'ConstructionSets, Schedules, Loads, and ProgramTypes. It will generally '
    +              'result in more read-able names for the resources in the OSM and IDF. '
    +              'Cases of duplicate IDs resulting from non-unique names will be resolved '
    +              'by adding integers to the ends of the new IDs that are derived from '
    +              'the name.', default=True, show_default=True)
    +@click.option('--log-file', '-log', help='Optional log file to output the paths to the '
    +              'generated OSM and IDF files if they were successfully created. '
    +              'By default this will be printed out to stdout',
    +              type=click.File('w'), default='-', show_default=True)
    +def model_to_osm_cli(
    +        model_file, sim_par_json, epw_file, multiplier, no_plenum, no_ceil_adjacency,
    +        folder, osm_file, idf_file, geometry_ids, resource_ids, log_file):
    +    """Translate a Dragonfly Model to an OpenStudio Model.
    +
    +    \b
    +    Args:
    +        model_file: Path to either a DFJSON or DFpkl file. This can also be a
    +            HBJSON or a HBpkl from which a Dragonfly model should be derived.
    +    """
    +    try:
    +        full_geometry = not multiplier
    +        plenum = not no_plenum
    +        ceil_adjacency = not no_ceil_adjacency
    +        geo_names = not geometry_ids
    +        res_names = not resource_ids
    +        model_to_osm(
    +            model_file, sim_par_json, epw_file, full_geometry, plenum, ceil_adjacency,
    +            folder, osm_file, idf_file, geo_names, res_names, log_file)
    +    except Exception as e:
    +        _logger.exception('Model translation failed.\n{}'.format(e))
    +        sys.exit(1)
    +    else:
    +        sys.exit(0)
    +
    +
    +
    +[docs] +def model_to_osm( + model_file, sim_par_json=None, epw_file=None, + full_geometry=False, plenum=False, ceil_adjacency=False, + folder=None, osm_file=None, idf_file=None, + geometry_names=False, resource_names=False, log_file=None, + multiplier=True, no_plenum=True, no_ceil_adjacency=True, + geometry_ids=True, resource_ids=True +): + """Translate a Dragonfly Model to an OpenStudio Model. + + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + sim_par_json: Full path to a honeybee energy SimulationParameter JSON that + describes all of the settings for the simulation. If None, default + parameters will be generated. + epw_file: Full path to an EPW file to be associated with the exported OSM. + This is typically not necessary but may be used when a sim-par-json is + specified that requests a HVAC sizing calculation to be run as part + of the translation process but no design days are inside this + simulation parameter. + full_geometry: Boolean to note if the multipliers on each Building story + will be passed along to the generated Honeybee Room objects or if + full geometry objects should be written for each story in the + building. (Default: False). + plenum: Boolean to indicate whether ceiling/floor plenums should be + auto-generated for the Rooms. (Default: False). + ceil_adjacency: Boolean to indicate whether adjacencies should be solved + between interior stories when Room2Ds perfectly match one another + in their floor plate. This ensures that Surface boundary conditions + are used instead of Adiabatic ones. Note that this input has no + effect when the object-per-model is Story. (Default: False). + folder: Folder on this computer, into which the working files, OSM and IDF + files will be written. If None, the files will be output in the + same location as the model_file. + osm_file: Optional path where the OSM will be copied after it is translated + in the folder. If None, the file will not be copied. + idf_file: Optional path where the IDF will be copied after it is translated + in the folder. If None, the file will not be copied. + geometry_names: Boolean to note whether a cleaned version of all geometry + display names should be used instead of identifiers when translating + the Model to OSM and IDF. Using this flag will affect all Rooms, Faces, + Apertures, Doors, and Shades. It will generally result in more read-able + names in the OSM and IDF but this means that it will not be easy to map + the EnergyPlus results back to the original Honeybee Model. Cases + of duplicate IDs resulting from non-unique names will be resolved + by adding integers to the ends of the new IDs that are derived from + the name. (Default: False). + resource_names: Boolean to note whether a cleaned version of all resource + display names should be used instead of identifiers when translating + the Model to OSM and IDF. Using this flag will affect all Materials, + Constructions, ConstructionSets, Schedules, Loads, and ProgramTypes. + It will generally result in more read-able names for the resources + in the OSM and IDF. Cases of duplicate IDs resulting from non-unique + names will be resolved by adding integers to the ends of the new IDs + that are derived from the name. (Default: False). + bypass_check: Boolean to note whether the Model should be re-serialized + to Python and checked before it is translated to .osm. The check is + not needed if the model-json was exported directly from the + honeybee-energy Python library. (Default: False). + log_file: Optional log file to output the paths to the generated OSM and] + IDF files if they were successfully created. By default this string + will be returned from this method. + """ + # set the default folder to the default if it's not specified + if folder is None: + folder = os.path.dirname(os.path.abspath(model_file)) + preparedir(folder, remove_content=False) + + # generate default simulation parameters + if sim_par_json is None: + sim_par = SimulationParameter() + sim_par.output.add_zone_energy_use() + sim_par.output.add_hvac_energy_use() + sim_par.output.add_electricity_generation() + sim_par.output.reporting_frequency = 'Monthly' + else: + with open(sim_par_json) as json_file: + data = json.load(json_file) + sim_par = SimulationParameter.from_dict(data) + + # perform a check to be sure the EPW file is specified for sizing runs + def ddy_from_epw(epw_file, sim_par): + """Produce a DDY from an EPW file.""" + epw_obj = EPW(epw_file) + des_days = [epw_obj.approximate_design_day('WinterDesignDay'), + epw_obj.approximate_design_day('SummerDesignDay')] + sim_par.sizing_parameter.design_days = des_days + + def write_sim_par(sim_par): + """Write simulation parameter object to a JSON.""" + sim_par_dict = sim_par.to_dict() + sp_json = os.path.abspath(os.path.join(folder, 'simulation_parameter.json')) + with open(sp_json, 'w') as fp: + json.dump(sim_par_dict, fp) + return sp_json + + if sim_par.sizing_parameter.efficiency_standard is not None: + assert epw_file is not None, 'An epw_file must be specified for ' \ + 'translation to OSM whenever a Simulation Parameter ' \ + 'efficiency_standard is specified.\nNo EPW was specified yet the ' \ + 'Simulation Parameter efficiency_standard is "{}".'.format( + sim_par.sizing_parameter.efficiency_standard + ) + epw_folder, epw_file_name = os.path.split(epw_file) + ddy_file = os.path.join(epw_folder, epw_file_name.replace('.epw', '.ddy')) + if len(sim_par.sizing_parameter.design_days) == 0 and \ + os.path.isfile(ddy_file): + try: + sim_par.sizing_parameter.add_from_ddy_996_004(ddy_file) + except AssertionError: # no design days within the DDY file + ddy_from_epw(epw_file, sim_par) + elif len(sim_par.sizing_parameter.design_days) == 0: + ddy_from_epw(epw_file, sim_par) + sim_par_json = write_sim_par(sim_par) + elif sim_par_json is None: + sim_par_json = write_sim_par(sim_par) + + # re-serialize the Dragonfly Model + model = Model.from_file(model_file) + model.convert_to_units('Meters') + + # convert Dragonfly Model to Honeybee + multiplier = not full_geometry + hb_models = model.to_honeybee( + object_per_model='District', use_multiplier=multiplier, + add_plenum=plenum, solve_ceiling_adjacencies=ceil_adjacency, + enforce_adj=False) + hb_model = hb_models[0] + + # create the HBJSON for input to OpenStudio CLI + hb_model_json = _measure_compatible_model_json( + hb_model, folder, use_geometry_names=geometry_names, + use_resource_names=resource_names) + + # Write the osw file to translate the model to osm + osw = to_openstudio_osw(folder, hb_model_json, sim_par_json, epw_file=epw_file) + + # run the measure to translate the model JSON to an openstudio measure + osm, idf = run_osw(osw) + # copy the resulting files to the specified locations + if idf is not None and os.path.isfile(idf): + if osm_file is not None: + if not osm_file.lower().endswith('.osm'): + osm_file = osm_file + '.osm' + shutil.copyfile(osm, osm_file) + if idf_file is not None: + if not idf_file.lower().endswith('.idf'): + idf_file = idf_file + '.idf' + shutil.copyfile(idf, idf_file) + if log_file is None: + return json.dumps([osm, idf], indent=4) + else: + log_file.write(json.dumps([osm, idf], indent=4)) + else: + _parse_os_cli_failure(folder)
    + + + +@translate.command('model-to-idf') +@click.argument('model-file', type=click.Path( + exists=True, file_okay=True, dir_okay=False, resolve_path=True)) +@click.option('--sim-par-json', '-sp', help='Full path to a honeybee energy ' + 'SimulationParameter JSON that describes all of the settings for ' + 'the simulation. If None default parameters will be generated.', + default=None, show_default=True, + type=click.Path(exists=True, file_okay=True, dir_okay=False, + resolve_path=True)) +@click.option('--multiplier/--full-geometry', ' /-fg', help='Flag to note if the ' + 'multipliers on each Building story will be passed along to the ' + 'generated Honeybee Room objects or if full geometry objects should be ' + 'written for each story in the building.', default=True, show_default=True) +@click.option('--no-plenum/--plenum', ' /-p', help='Flag to indicate whether ' + 'ceiling/floor plenums should be auto-generated for the Rooms.', + default=True, show_default=True) +@click.option('--no-ceil-adjacency/--ceil-adjacency', ' /-a', help='Flag to indicate ' + 'whether adjacencies should be solved between interior stories when ' + 'Room2Ds perfectly match one another in their floor plate. This ensures ' + 'that Surface boundary conditions are used instead of Adiabatic ones. ' + 'Note that this input has no effect when the object-per-model is Story.', + default=True, show_default=True) +@click.option('--additional-str', '-a', help='Text string for additional lines that ' + 'should be added to the IDF.', type=str, default='', show_default=True) +@click.option('--compact-schedules/--csv-schedules', ' /-c', help='Flag to note ' + 'whether any ScheduleFixedIntervals in the model should be included ' + 'in the IDF string as a Schedule:Compact or they should be written as ' + 'CSV Schedule:File and placed in a directory next to the output-file.', + default=True, show_default=True) +@click.option('--hvac-to-ideal-air/--hvac-check', ' /-h', help='Flag to note ' + 'whether any detailed HVAC system templates should be converted to ' + 'an equivalent IdealAirSystem upon export. If hvac-check is used' + 'and the Model contains detailed systems, a ValueError will ' + 'be raised.', default=True, show_default=True) +@click.option('--geometry-ids/--geometry-names', ' /-gn', help='Flag to note whether a ' + 'cleaned version of all geometry display names should be used instead ' + 'of identifiers when translating the Model to IDF. Using this flag will ' + 'affect all Rooms, Faces, Apertures, Doors, and Shades. It will ' + 'generally result in more read-able names in the IDF but this means that ' + 'it will not be easy to map the EnergyPlus results back to the original ' + 'Honeybee Model. Cases of duplicate IDs resulting from non-unique names ' + 'will be resolved by adding integers to the ends of the new IDs that are ' + 'derived from the name.', default=True, show_default=True) +@click.option('--resource-ids/--resource-names', ' /-rn', help='Flag to note whether a ' + 'cleaned version of all resource display names should be used instead ' + 'of identifiers when translating the Model to IDF. Using this flag will ' + 'affect all Materials, Constructions, ConstructionSets, Schedules, ' + 'Loads, and ProgramTypes. It will generally result in more read-able ' + 'names for the resources in the IDF. Cases of duplicate IDs resulting ' + 'from non-unique names will be resolved by adding integers to the ends ' + 'of the new IDs that are derived from the name.', + default=True, show_default=True) +@click.option('--output-file', '-f', help='Optional IDF file to output the IDF string ' + 'of the translation. By default this will be printed out to stdout', + type=click.File('w'), default='-', show_default=True) +def model_to_idf_cli( + model_file, sim_par_json, multiplier, no_plenum, no_ceil_adjacency, + additional_str, compact_schedules, hvac_to_ideal_air, + geometry_ids, resource_ids, output_file +): + """Translate a Dragonfly Model to an IDF using direct-to-idf translators. + + The resulting IDF should be simulate-able but not all Model properties might + make it into the IDF given that the direct-to-idf translators are used. + + \b + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + """ + try: + full_geometry = not multiplier + plenum = not no_plenum + ceil_adjacency = not no_ceil_adjacency + csv_schedules = not compact_schedules + hvac_check = not hvac_to_ideal_air + geo_names = not geometry_ids + res_names = not resource_ids + model_to_idf( + model_file, sim_par_json, full_geometry, plenum, ceil_adjacency, + additional_str, csv_schedules, + hvac_check, geo_names, res_names, output_file) + except Exception as e: + _logger.exception('Model translation failed.\n{}\n'.format(e)) + sys.exit(1) + else: + sys.exit(0) + + +
    +[docs] +def model_to_idf( + model_file, sim_par_json=None, + full_geometry=False, plenum=False, ceil_adjacency=False, + additional_str='', csv_schedules=False, hvac_check=False, + geometry_names=False, resource_names=False, output_file=None, + multiplier=True, no_plenum=True, no_ceil_adjacency=True, + compact_schedules=True, hvac_to_ideal_air=True, geometry_ids=True, resource_ids=True +): + """Translate a Dragonfly Model to an IDF using direct-to-idf translators. + + The resulting IDF should be simulate-able but not all Model properties might + make it into the IDF given that the direct-to-idf translators are used. + + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + sim_par_json: Full path to a honeybee energy SimulationParameter JSON that + describes all of the settings for the simulation. If None, default + parameters will be generated. + full_geometry: Boolean to note if the multipliers on each Building story + will be passed along to the generated Honeybee Room objects or if + full geometry objects should be written for each story in the + building. (Default: False). + plenum: Boolean to indicate whether ceiling/floor plenums should be + auto-generated for the Rooms. (Default: False). + ceil_adjacency: Boolean to indicate whether adjacencies should be solved + between interior stories when Room2Ds perfectly match one another + in their floor plate. This ensures that Surface boundary conditions + are used instead of Adiabatic ones. Note that this input has no + effect when the object-per-model is Story. (Default: False). + additional_str: Text string for additional lines that should be added + to the IDF. + csv_schedules: Boolean to note whether any ScheduleFixedIntervals in the + model should be included in the IDF string as a Schedule:Compact or + they should be written as CSV Schedule:File and placed in a directory + next to the output_file. (Default: False). + hvac_check: Boolean to note whether any detailed HVAC system templates + should be converted to an equivalent IdealAirSystem upon export. + If hvac-check is used and the Model contains detailed systems, a + ValueError will be raised. (Default: False). + geometry_names: Boolean to note whether a cleaned version of all geometry + display names should be used instead of identifiers when translating + the Model to OSM and IDF. Using this flag will affect all Rooms, Faces, + Apertures, Doors, and Shades. It will generally result in more read-able + names in the OSM and IDF but this means that it will not be easy to map + the EnergyPlus results back to the original Honeybee Model. Cases + of duplicate IDs resulting from non-unique names will be resolved + by adding integers to the ends of the new IDs that are derived from + the name. (Default: False). + resource_names: Boolean to note whether a cleaned version of all resource + display names should be used instead of identifiers when translating + the Model to OSM and IDF. Using this flag will affect all Materials, + Constructions, ConstructionSets, Schedules, Loads, and ProgramTypes. + It will generally result in more read-able names for the resources + in the OSM and IDF. Cases of duplicate IDs resulting from non-unique + names will be resolved by adding integers to the ends of the new IDs + that are derived from the name. (Default: False). + output_file: Optional IDF file to output the IDF string of the translation. + By default this string will be returned from this method. + """ + # check that the simulation parameters are there and load them + if sim_par_json is not None: + with open(sim_par_json) as json_file: + data = json.load(json_file) + sim_par = SimulationParameter.from_dict(data) + else: + sim_par = SimulationParameter() + sim_par.output.add_zone_energy_use() + sim_par.output.add_hvac_energy_use() + sim_par.output.add_electricity_generation() + sim_par.output.reporting_frequency = 'Monthly' + + # re-serialize the Dragonfly Model + model = Model.from_file(model_file) + model.convert_to_units('Meters') + + # convert Dragonfly Model to Honeybee + multiplier = not full_geometry + hb_models = model.to_honeybee( + object_per_model='District', use_multiplier=multiplier, + add_plenum=plenum, solve_ceiling_adjacencies=ceil_adjacency, + enforce_adj=False) + hb_model = hb_models[0] + + # reset the IDs to be derived from the display_names if requested + if geometry_names: + model.reset_ids() + if resource_names: + model.properties.energy.reset_resource_ids() + + # set the schedule directory in case it is needed + sch_directory = None + if csv_schedules: + sch_path = os.path.abspath(model_file) if 'stdout' in str(output_file) \ + else os.path.abspath(str(output_file)) + sch_directory = os.path.join(os.path.split(sch_path)[0], 'schedules') + + # create the strings for simulation parameters and model + ver_str = energyplus_idf_version() if folders.energyplus_version \ + is not None else '' + sim_par_str = sim_par.to_idf() + hvac_to_ideal_air = not hvac_check + model_str = hb_model.to.idf( + hb_model, schedule_directory=sch_directory, + use_ideal_air_equivalent=hvac_to_ideal_air) + idf_str = '\n\n'.join([ver_str, sim_par_str, model_str, additional_str]) + + # write out the result + return process_content_to_output(idf_str, output_file)
    + + + +@translate.command('model-to-gbxml') +@click.argument('model-file', type=click.Path( + exists=True, file_okay=True, dir_okay=False, resolve_path=True)) +@click.option('--multiplier/--full-geometry', ' /-fg', help='Flag to note if the ' + 'multipliers on each Building story will be passed along to the ' + 'generated Honeybee Room objects or if full geometry objects should be ' + 'written for each story in the building.', default=True, show_default=True) +@click.option('--no-plenum/--plenum', ' /-p', help='Flag to indicate whether ' + 'ceiling/floor plenums should be auto-generated for the Rooms.', + default=True, show_default=True) +@click.option('--no-ceil-adjacency/--ceil-adjacency', ' /-a', help='Flag to indicate ' + 'whether adjacencies should be solved between interior stories when ' + 'Room2Ds perfectly match one another in their floor plate. This ensures ' + 'that Surface boundary conditions are used instead of Adiabatic ones. ' + 'Note that this input has no effect when the object-per-model is Story.', + default=True, show_default=True) +@click.option('--osw-folder', '-osw', help='Folder on this computer, into which the ' + 'working files will be written. If None, it will be written into the a ' + 'temp folder in the default simulation folder.', default=None, + type=click.Path(file_okay=False, dir_okay=True, resolve_path=True)) +@click.option('--default-subfaces/--triangulate-subfaces', ' /-t', + help='Flag to note whether sub-faces (including Apertures and Doors) ' + 'should be triangulated if they have more than 4 sides (True) or whether ' + 'they should be left as they are (False). This triangulation is ' + 'necessary when exporting directly to EnergyPlus since it cannot accept ' + 'sub-faces with more than 4 vertices.', default=True, show_default=True) +@click.option('--triangulate-non-planar/--permit-non-planar', ' /-np', + help='Flag to note whether any non-planar orphaned geometry in the ' + 'model should be triangulated upon export. This can be helpful because ' + 'OpenStudio simply raises an error when it encounters non-planar ' + 'geometry, which would hinder the ability to save gbXML files that are ' + 'to be corrected in other software.', default=True, show_default=True) +@click.option('--minimal/--complete-geometry', ' /-cg', help='Flag to note whether space ' + 'boundaries and shell geometry should be included in the exported ' + 'gbXML vs. just the minimal required non-manifold geometry.', + default=True, show_default=True) +@click.option('--interior-face-type', '-ift', help='Text string for the type to be ' + 'used for all interior floor faces. If unspecified, the interior types ' + 'will be left as they are. Choose from: InteriorFloor, Ceiling.', + type=str, default='', show_default=True) +@click.option('--ground-face-type', '-gft', help='Text string for the type to be ' + 'used for all ground-contact floor faces. If unspecified, the ground ' + 'types will be left as they are. Choose from: UndergroundSlab, ' + 'SlabOnGrade, RaisedFloor.', type=str, default='', show_default=True) +@click.option('--output-file', '-f', help='Optional gbXML file to output the string ' + 'of the translation. By default it printed out to stdout', default='-', + type=click.Path(file_okay=True, dir_okay=False, resolve_path=True)) +def model_to_gbxml_cli( + model_file, multiplier, no_plenum, no_ceil_adjacency, + osw_folder, default_subfaces, triangulate_non_planar, minimal, + interior_face_type, ground_face_type, output_file +): + """Translate a Dragonfly Model to a gbXML file. + + \b + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + """ + try: + full_geometry = not multiplier + plenum = not no_plenum + ceil_adjacency = not no_ceil_adjacency + triangulate_subfaces = not default_subfaces + permit_non_planar = not triangulate_non_planar + complete_geometry = not minimal + model_to_gbxml( + model_file, osw_folder, full_geometry, plenum, ceil_adjacency, + triangulate_subfaces, permit_non_planar, complete_geometry, + interior_face_type, ground_face_type, output_file) + except Exception as e: + _logger.exception('Model translation failed.\n{}'.format(e)) + sys.exit(1) + else: + sys.exit(0) + + +
    +[docs] +def model_to_gbxml( + model_file, osw_folder=None, full_geometry=False, plenum=False, ceil_adjacency=False, + triangulate_subfaces=False, permit_non_planar=False, complete_geometry=False, + interior_face_type='', ground_face_type='', output_file=None, + multiplier=True, no_plenum=True, no_ceil_adjacency=True, + default_subfaces=True, triangulate_non_planar=True, minimal=True, +): + """Translate a Dragonfly Model to a gbXML file. + + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + osw_folder: Folder on this computer, into which the working files will + be written. If None, it will be written into a temp folder in the + default simulation folder. + full_geometry: Boolean to note if the multipliers on each Building story + will be passed along to the generated Honeybee Room objects or if + full geometry objects should be written for each story in the + building. (Default: False). + plenum: Boolean to indicate whether ceiling/floor plenums should be + auto-generated for the Rooms. (Default: False). + ceil_adjacency: Boolean to indicate whether adjacencies should be solved + between interior stories when Room2Ds perfectly match one another + in their floor plate. This ensures that Surface boundary conditions + are used instead of Adiabatic ones. Note that this input has no + effect when the object-per-model is Story. (Default: False). + triangulate_subfaces: Boolean to note whether sub-faces (including + Apertures and Doors) should be triangulated if they have more + than 4 sides (True) or whether they should be left as they are (False). + This triangulation is necessary when exporting directly to EnergyPlus + since it cannot accept sub-faces with more than 4 vertices. (Default: False). + permit_non_planar: Boolean to note whether any non-planar orphaned geometry + in the model should be triangulated upon export. This can be helpful + because OpenStudio simply raises an error when it encounters non-planar + geometry, which would hinder the ability to save gbXML files that are + to be corrected in other software. (Default: False). + complete_geometry: Boolean to note whether space boundaries and shell geometry + should be included in the exported gbXML vs. just the minimal required + non-manifold geometry. (Default: False). + interior_face_type: Text string for the type to be used for all interior + floor faces. If unspecified, the interior types will be left as they are. + Choose from: InteriorFloor, Ceiling. + ground_face_type: Text string for the type to be used for all ground-contact + floor faces. If unspecified, the ground types will be left as they are. + Choose from: UndergroundSlab, SlabOnGrade, RaisedFloor. + bypass_check: Boolean to note whether the Model should be re-serialized + to Python and checked before it is translated to .osm. The check is + not needed if the model-json was exported directly from the + honeybee-energy Python library. (Default: False). + output_file: Optional gbXML file to output the string of the translation. + By default it will be returned from this method. + """ + # set the default folder if it's not specified + out_path = None + out_directory = os.path.join( + hb_folders.default_simulation_folder, 'temp_translate') + if output_file.endswith('-'): + f_name = os.path.basename(model_file).lower() + f_name = f_name.replace('.dfjson', '.xml').replace('.json', '.xml') + f_name = f_name.replace('.dfplk', '.xml').replace('.pkl', '.xml') + f_name = f_name.replace('.hbjson', '.xml').replace('.hbpkl', '.xml') + out_path = os.path.join(out_directory, f_name) + elif output_file.endswith('.gbxml'): # avoid OpenStudio complaining about .gbxml + f_name = os.path.basename(model_file).lower() + f_name = f_name.replace('.gbxml', '.xml') + out_path = os.path.join(out_directory, f_name) + preparedir(out_directory) + + # re-serialize the Dragonfly Model + model = Model.from_dfjson(model_file) + model.convert_to_units('Meters') + + # convert Dragonfly Model to Honeybee + multiplier = not full_geometry + hb_models = model.to_honeybee( + object_per_model='District', use_multiplier=multiplier, + add_plenum=plenum, solve_ceiling_adjacencies=ceil_adjacency, + enforce_adj=False) + hb_model = hb_models[0] + + # create the dictionary of the HBJSON for input to OpenStudio CLI + tri_non_planar = not permit_non_planar + hb_model_json = _measure_compatible_model_json( + hb_model, out_directory, simplify_window_cons=True, + triangulate_sub_faces=triangulate_subfaces, + triangulate_non_planar_orphaned=tri_non_planar) + + # Write the osw file and translate the model to gbXML + out_f = out_path if output_file is None or output_file.endswith('-') else output_file + osw = to_gbxml_osw(hb_model_json, out_f, osw_folder) + if not complete_geometry and not (interior_face_type or ground_face_type): + file_contents = _run_translation_osw(osw, out_path) + else: + _, idf = run_osw(osw, silent=True) + if idf is not None and os.path.isfile(idf): + if interior_face_type or ground_face_type: + int_ft = interior_face_type if interior_face_type != '' else None + gnd_ft = ground_face_type if ground_face_type != '' else None + set_gbxml_floor_types(out_f, int_ft, gnd_ft) + if complete_geometry: + add_gbxml_space_boundaries(out_f, hb_model) + if out_path is not None: # load the JSON string to stdout + with open(out_path) as json_file: + file_contents = json_file.read() + else: + _parse_os_cli_failure(osw_folder) + + # return the file contents if requested + if file_contents is not None: + if output_file is None: + return file_contents + else: + print(file_contents)
    + + + +@translate.command('model-to-trace-gbxml') +@click.argument('model-file', type=click.Path( + exists=True, file_okay=True, dir_okay=False, resolve_path=True)) +@click.option('--multiplier/--full-geometry', ' /-fg', help='Flag to note if the ' + 'multipliers on each Building story will be passed along to the ' + 'generated Honeybee Room objects or if full geometry objects should be ' + 'written for each story in the building.', default=True, show_default=True) +@click.option('--no-plenum/--plenum', ' /-p', help='Flag to indicate whether ' + 'ceiling/floor plenums should be auto-generated for the Rooms.', + default=True, show_default=True) +@click.option('--no-ceil-adjacency/--ceil-adjacency', ' /-a', help='Flag to indicate ' + 'whether adjacencies should be solved between interior stories when ' + 'Room2Ds perfectly match one another in their floor plate. This ensures ' + 'that Surface boundary conditions are used instead of Adiabatic ones. ' + 'Note that this input has no effect when the object-per-model is Story.', + default=True, show_default=True) +@click.option('--single-window/--detailed-windows', ' /-fg', help='Flag to note ' + 'whether all windows within walls should be converted to a single ' + 'window with an area that matches the original geometry.', + default=True, show_default=True) +@click.option('--rect-sub-distance', '-r', help='A number for the resolution at which ' + 'non-rectangular Apertures will be subdivided into smaller rectangular ' + 'units. This is required as TRACE 3D plus cannot model non-rectangular ' + 'geometries. This can include the units of the distance (eg. 0.5ft) or, ' + 'if no units are provided, the value will be interpreted in the ' + 'honeybee model units.', + type=str, default='0.15m', show_default=True) +@click.option('--frame-merge-distance', '-m', help='A number for the maximum distance ' + 'between non-rectangular Apertures at which point the Apertures will be ' + 'merged into a single rectangular geometry. This is often helpful when ' + 'there are several triangular Apertures that together make a rectangle ' + 'when they are merged across their frames. This can include the units ' + 'of the distance (eg. 0.5ft) or, if no units are provided, the value ' + 'will be interpreted in the honeybee model units', + type=str, default='0.2m', show_default=True) +@click.option('--osw-folder', '-osw', help='Folder on this computer, into which the ' + 'working files will be written. If None, it will be written into a ' + 'temp folder in the default simulation folder.', default=None, + type=click.Path(file_okay=False, dir_okay=True, resolve_path=True)) +@click.option('--output-file', '-f', help='Optional gbXML file to output the string ' + 'of the translation. By default it printed out to stdout.', default='-', + type=click.Path(file_okay=True, dir_okay=False, resolve_path=True)) +def model_to_trace_gbxml_cli( + model_file, multiplier, no_plenum, no_ceil_adjacency, + single_window, rect_sub_distance, frame_merge_distance, + osw_folder, output_file +): + """Translate a Dragonfly Model to a TRACE-compatible gbXML file. + + \b + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + """ + try: + full_geometry = not multiplier + plenum = not no_plenum + ceil_adjacency = not no_ceil_adjacency + detailed_windows = not single_window + model_to_trace_gbxml( + model_file, full_geometry, plenum, ceil_adjacency, detailed_windows, + rect_sub_distance, frame_merge_distance, osw_folder, output_file) + except Exception as e: + _logger.exception('Model translation failed.\n{}'.format(e)) + sys.exit(1) + else: + sys.exit(0) + + +
    +[docs] +def model_to_trace_gbxml( + model_file, full_geometry=False, plenum=False, ceil_adjacency=False, + detailed_windows=False, rect_sub_distance='0.15m', + frame_merge_distance='0.2m', osw_folder=None, output_file=None, + multiplier=True, no_plenum=True, no_ceil_adjacency=True, single_window=True +): + """Translate a Dragonfly Model to a gbXML file that is compatible with TRACE. + + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + full_geometry: Boolean to note if the multipliers on each Building story + will be passed along to the generated Honeybee Room objects or if + full geometry objects should be written for each story in the + building. (Default: False). + plenum: Boolean to indicate whether ceiling/floor plenums should be + auto-generated for the Rooms. (Default: False). + ceil_adjacency: Boolean to indicate whether adjacencies should be solved + between interior stories when Room2Ds perfectly match one another + in their floor plate. This ensures that Surface boundary conditions + are used instead of Adiabatic ones. Note that this input has no + effect when the object-per-model is Story. (Default: False). + detailed_windows: A boolean for whether all windows within walls should be + left as they are (True) or converted to a single window with an area + that matches the original geometry (False). (Default: False). + rect_sub_distance: A number for the resolution at which non-rectangular + Apertures will be subdivided into smaller rectangular units. This is + required as TRACE 3D plus cannot model non-rectangular geometries. + This can include the units of the distance (eg. 0.5ft) or, if no units + are provided, the value will be interpreted in the honeybee model + units. (Default: 0.15m). + frame_merge_distance: A number for the maximum distance between non-rectangular + Apertures at which point the Apertures will be merged into a single + rectangular geometry. This is often helpful when there are several + triangular Apertures that together make a rectangle when they are + merged across their frames. This can include the units of the + distance (eg. 0.5ft) or, if no units are provided, the value will + be interpreted in the honeybee model units. (Default: 0.2m). + osw_folder: Folder on this computer, into which the working files will + be written. If None, it will be written into a temp folder in the + default simulation folder. + output_file: Optional gbXML file to output the string of the translation. + By default it will be returned from this method. + """ + # set the default folder if it's not specified + out_path = None + out_directory = os.path.join( + hb_folders.default_simulation_folder, 'temp_translate') + if output_file.endswith('-'): + f_name = os.path.basename(model_file).lower() + f_name = f_name.replace('.dfjson', '.xml').replace('.json', '.xml') + f_name = f_name.replace('.dfplk', '.xml').replace('.pkl', '.xml') + f_name = f_name.replace('.hbjson', '.xml').replace('.hbpkl', '.xml') + out_path = os.path.join(out_directory, f_name) + elif output_file.endswith('.gbxml'): # avoid OpenStudio complaining about .gbxml + f_name = os.path.basename(model_file).lower() + f_name = f_name.replace('.gbxml', '.xml') + out_path = os.path.join(out_directory, f_name) + preparedir(out_directory) + + # re-serialize the Dragonfly Model + model = Model.from_dfjson(model_file) + model.convert_to_units('Meters') + + # convert Dragonfly Model to Honeybee + multiplier = not full_geometry + hb_models = model.to_honeybee( + object_per_model='District', use_multiplier=multiplier, + add_plenum=plenum, solve_ceiling_adjacencies=ceil_adjacency, + enforce_adj=False) + hb_model = hb_models[0] + hb_model_file = os.path.join(out_directory) + with open(hb_model_file, 'w', encoding='utf-8') as hmf: + json.dump(hb_model.to_dict(), hmf, ensure_ascii=False) + + # run the Model re-serialization and check if specified + single_window = not detailed_windows + hb_model_file = trace_compatible_model_json( + hb_model_file, out_directory, single_window, + rect_sub_distance, frame_merge_distance) + + # Write the osw file and translate the model to gbXML + out_f = out_path if output_file is None or output_file.endswith('-') else output_file + osw = to_gbxml_osw(model_file, out_f, osw_folder) + file_contents = _run_translation_osw(osw, out_path) + + # return the file contents if requested + if file_contents is not None: + if output_file is None: + return file_contents + else: + print(file_contents)
    + + + +@translate.command('model-to-sdd') +@click.argument('model-file', type=click.Path( + exists=True, file_okay=True, dir_okay=False, resolve_path=True)) +@click.option('--multiplier/--full-geometry', ' /-fg', help='Flag to note if the ' + 'multipliers on each Building story will be passed along to the ' + 'generated Honeybee Room objects or if full geometry objects should be ' + 'written for each story in the building.', default=True, show_default=True) +@click.option('--no-plenum/--plenum', ' /-p', help='Flag to indicate whether ' + 'ceiling/floor plenums should be auto-generated for the Rooms.', + default=True, show_default=True) +@click.option('--no-ceil-adjacency/--ceil-adjacency', ' /-a', help='Flag to indicate ' + 'whether adjacencies should be solved between interior stories when ' + 'Room2Ds perfectly match one another in their floor plate. This ensures ' + 'that Surface boundary conditions are used instead of Adiabatic ones. ' + 'Note that this input has no effect when the object-per-model is Story.', + default=True, show_default=True) +@click.option('--osw-folder', '-osw', help='Folder on this computer, into which the ' + 'working files will be written. If None, it will be written into the a ' + 'temp folder in the default simulation folder.', default=None, + type=click.Path(file_okay=False, dir_okay=True, resolve_path=True)) +@click.option('--geometry-ids/--geometry-names', ' /-gn', help='Flag to note whether a ' + 'cleaned version of all geometry display names should be used instead ' + 'of identifiers when translating the Model to SDD. Using this flag will ' + 'affect all Rooms, Faces, Apertures, Doors, and Shades. It will ' + 'generally result in more read-able names in the SDD but this means that ' + 'it will not be easy to map the EnergyPlus results back to the original ' + 'Honeybee Model. Cases of duplicate IDs resulting from non-unique names ' + 'will be resolved by adding integers to the ends of the new IDs that are ' + 'derived from the name.', default=True, show_default=True) +@click.option('--resource-ids/--resource-names', ' /-rn', help='Flag to note whether a ' + 'cleaned version of all resource display names should be used instead ' + 'of identifiers when translating the Model to SDD. Using this flag will ' + 'affect all Materials, Constructions, ConstructionSets, Schedules, ' + 'Loads, and ProgramTypes. It will generally result in more read-able ' + 'names for the resources in the SDD. Cases of duplicate IDs resulting ' + 'from non-unique names will be resolved by adding integers to the ends ' + 'of the new IDs that are derived from the name.', + default=True, show_default=True) +@click.option('--output-file', '-f', help='Optional gbXML file to output the string ' + 'of the translation. By default it printed out to stdout', default='-', + type=click.Path(file_okay=True, dir_okay=False, resolve_path=True)) +def model_to_sdd_cli( + model_file, multiplier, no_plenum, no_ceil_adjacency, osw_folder, + geometry_ids, resource_ids, output_file +): + """Translate a Dragonfly Model to a CBECC SDD file. + + \b + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + """ + try: + full_geometry = not multiplier + plenum = not no_plenum + ceil_adjacency = not no_ceil_adjacency + geo_names = not geometry_ids + res_names = not resource_ids + model_to_sdd( + model_file, full_geometry, plenum, ceil_adjacency, + osw_folder, geo_names, res_names, output_file) + except Exception as e: + _logger.exception('Model translation failed.\n{}'.format(e)) + sys.exit(1) + else: + sys.exit(0) + + +
    +[docs] +def model_to_sdd( + model_file, full_geometry=False, plenum=False, ceil_adjacency=False, + osw_folder=None, geometry_names=False, resource_names=False, output_file=None, + multiplier=True, no_plenum=True, no_ceil_adjacency=True, + geometry_ids=True, resource_ids=True +): + """Translate a Dragonfly Model to a CBECC SDD file. + + Args: + model_file: Path to either a DFJSON or DFpkl file. This can also be a + HBJSON or a HBpkl from which a Dragonfly model should be derived. + full_geometry: Boolean to note if the multipliers on each Building story + will be passed along to the generated Honeybee Room objects or if + full geometry objects should be written for each story in the + building. (Default: False). + plenum: Boolean to indicate whether ceiling/floor plenums should be + auto-generated for the Rooms. (Default: False). + ceil_adjacency: Boolean to indicate whether adjacencies should be solved + between interior stories when Room2Ds perfectly match one another + in their floor plate. This ensures that Surface boundary conditions + are used instead of Adiabatic ones. Note that this input has no + effect when the object-per-model is Story. (Default: False). + osw_folder: Folder on this computer, into which the working files will + be written. If None, it will be written into a temp folder in the + default simulation folder. + geometry_names: Boolean to note whether a cleaned version of all geometry + display names should be used instead of identifiers when translating + the Model to OSM and IDF. Using this flag will affect all Rooms, Faces, + Apertures, Doors, and Shades. It will generally result in more read-able + names in the OSM and IDF but this means that it will not be easy to map + the EnergyPlus results back to the original Honeybee Model. Cases + of duplicate IDs resulting from non-unique names will be resolved + by adding integers to the ends of the new IDs that are derived from + the name. (Default: False). + resource_names: Boolean to note whether a cleaned version of all resource + display names should be used instead of identifiers when translating + the Model to OSM and IDF. Using this flag will affect all Materials, + Constructions, ConstructionSets, Schedules, Loads, and ProgramTypes. + It will generally result in more read-able names for the resources + in the OSM and IDF. Cases of duplicate IDs resulting from non-unique + names will be resolved by adding integers to the ends of the new IDs + that are derived from the name. (Default: False). + output_file: Optional SDD file to output the string of the translation. + By default it will be returned from this method. + """ + # set the default folder if it's not specified + out_path = None + out_directory = os.path.join( + hb_folders.default_simulation_folder, 'temp_translate') + if output_file.endswith('-'): + f_name = os.path.basename(model_file).lower() + f_name = f_name.replace('.dfjson', '.xml').replace('.json', '.xml') + f_name = f_name.replace('.dfplk', '.xml').replace('.pkl', '.xml') + f_name = f_name.replace('.hbjson', '.xml').replace('.hbpkl', '.xml') + out_path = os.path.join(out_directory, f_name) + elif output_file.endswith('.gbxml'): # avoid OpenStudio complaining about .gbxml + f_name = os.path.basename(model_file).lower() + f_name = f_name.replace('.gbxml', '.xml') + out_path = os.path.join(out_directory, f_name) + preparedir(out_directory) + + # re-serialize the Dragonfly Model + model = Model.from_dfjson(model_file) + model.convert_to_units('Meters') + + # convert Dragonfly Model to Honeybee + multiplier = not full_geometry + hb_models = model.to_honeybee( + object_per_model='District', use_multiplier=multiplier, + add_plenum=plenum, solve_ceiling_adjacencies=ceil_adjacency, + enforce_adj=False) + hb_model = hb_models[0] + + # create the dictionary of the HBJSON for input to OpenStudio CLI + hb_model_json = _measure_compatible_model_json( + hb_model, out_directory, simplify_window_cons=True, + triangulate_sub_faces=True, use_geometry_names=geometry_names, + use_resource_names=resource_names) + + # Write the osw file and translate the model to SDD + out_f = out_path if output_file.endswith('-') else output_file + osw = to_sdd_osw(hb_model_json, out_f, osw_folder) + file_contents = _run_translation_osw(osw, out_path) + + # return the file contents if requested + if file_contents is not None: + if output_file is None: + return file_contents + else: + print(file_contents)
    + + + +def _run_translation_osw(osw, out_path): + """Generic function used by all import methods that run OpenStudio CLI.""" + # run the measure to translate the model JSON to an openstudio measure + _, idf = run_osw(osw, silent=True) + if idf is not None and os.path.isfile(idf): + if out_path is not None: # load the JSON string to stdout + with open(out_path) as json_file: + print(json_file.read()) + else: + _parse_os_cli_failure(os.path.dirname(osw)) + + +def _measure_compatible_model_json( + parsed_model, destination_directory, simplify_window_cons=False, + triangulate_sub_faces=True, triangulate_non_planar_orphaned=False, + use_geometry_names=False, use_resource_names=False): + """Convert a Honeybee Model to a HBJSON compatible with the honeybee_openstudio_gem. + + Args: + parsed_model: A honeybee Model object. + destination_directory: The directory into which the Model JSON that is + compatible with the honeybee_openstudio_gem should be written. If None, + this will be the same location as the input model_json_path. (Default: None). + simplify_window_cons: Boolean to note whether window constructions should + be simplified during the translation. This is useful when the ultimate + destination of the OSM is a format that does not supported layered + window constructions (like gbXML). (Default: False). + triangulate_sub_faces: Boolean to note whether sub-faces (including + Apertures and Doors) should be triangulated if they have more than + 4 sides (True) or whether they should be left as they are (False). + This triangulation is necessary when exporting directly to EnergyPlus + since it cannot accept sub-faces with more than 4 vertices. (Default: True). + triangulate_non_planar_orphaned: Boolean to note whether any non-planar + orphaned geometry in the model should be triangulated upon export. + This can be helpful because OpenStudio simply raises an error when + it encounters non-planar geometry, which would hinder the ability + to save gbXML files that are to be corrected in other + software. (Default: False). + enforce_rooms: Boolean to note whether this method should enforce the + presence of Rooms in the Model, which is as necessary prerequisite + for simulation in EnergyPlus. (Default: False). + use_geometry_names: Boolean to note whether a cleaned version of all + geometry display names should be used instead of identifiers when + translating the Model to OSM and IDF. Using this flag will affect + all Rooms, Faces, Apertures, Doors, and Shades. It will generally + result in more read-able names in the OSM and IDF but this means + that it will not be easy to map the EnergyPlus results back to the + input Honeybee Model. Cases of duplicate IDs resulting from + non-unique names will be resolved by adding integers to the ends + of the new IDs that are derived from the name. (Default: False). + use_resource_names: Boolean to note whether a cleaned version of all + resource display names should be used instead of identifiers when + translating the Model to OSM and IDF. Using this flag will affect + all Materials, Constructions, ConstructionSets, Schedules, Loads, + and ProgramTypes. It will generally result in more read-able names + for the resources in the OSM and IDF. Cases of duplicate IDs + resulting from non-unique names will be resolved by adding integers + to the ends of the new IDs that are derived from the name. (Default: False). + + Returns: + The full file path to the new Model JSON written out by this method. + """ + # remove degenerate geometry within native E+ tolerance of 0.01 meters + try: + parsed_model.remove_degenerate_geometry(0.01) + except ValueError as e: + error = 'Failed to remove degenerate Rooms.\n{}'.format(e) + raise ValueError(error) + if triangulate_non_planar_orphaned: + parsed_model.triangulate_non_planar_quads(0.01) + + # remove the HVAC from any Rooms lacking setpoints + rem_msgs = parsed_model.properties.energy.remove_hvac_from_no_setpoints() + if len(rem_msgs) != 0: + print('\n'.join(rem_msgs)) + + # reset the IDs to be derived from the display_names if requested + if use_geometry_names: + parsed_model.reset_ids() + if use_resource_names: + parsed_model.properties.energy.reset_resource_ids() + + # get the dictionary representation of the Model and add auto-calculated properties + model_dict = parsed_model.to_dict(triangulate_sub_faces=triangulate_sub_faces) + parsed_model.properties.energy.add_autocal_properties_to_dict(model_dict) + if simplify_window_cons: + parsed_model.properties.energy.simplify_window_constructions_in_dict(model_dict) + + # write the dictionary into a file + dest_file_path = os.path.join(destination_directory, 'in.hbjson') + preparedir(destination_directory, remove_content=False) # create the directory + with open(dest_file_path, 'w', encoding='utf-8') as fp: + json.dump(model_dict, fp, ensure_ascii=False) + + return os.path.abspath(dest_file_path) +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/config.html b/docs/_modules/dragonfly_energy/config.html new file mode 100644 index 00000000..7156b81f --- /dev/null +++ b/docs/_modules/dragonfly_energy/config.html @@ -0,0 +1,1417 @@ + + + + + + + dragonfly_energy.config — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.config

    +"""dragonfly_energy configurations.
    +
    +Import this into every module where access configurations are needed.
    +
    +Usage:
    +
    +.. code-block:: python
    +
    +    from dragonfly_energy.config import folders
    +    print(folders.mapper_path)
    +    folders.mapper_path = "C:/Urbanopt_test/Honeybee.rb"
    +"""
    +from ladybug.futil import write_to_file
    +import honeybee_energy.config as hb_energy_config
    +
    +import os
    +import platform
    +import json
    +import subprocess
    +
    +
    +
    +[docs] +class Folders(object): + """Dragonfly_energy folders. + + Args: + config_file: The path to the config.json file from which folders are loaded. + If None, the config.json module included in this package will be used. + Default: None. + mute: If False, the paths to the various folders will be printed as they + are found. If True, no printing will occur upon initialization of this + class. Default: True. + + Properties: + * mapper_path + * urbanopt_gemfile_path + * urbanopt_cli_path + * urbanopt_env_path + * urbanopt_version + * urbanopt_version_str + * reopt_assumptions_path + * docker_version + * docker_version_str + * config_file + * mute + """ + URBANOPT_VERSION = (0, 14, 0) + COMPATIBILITY_URL = 'https://github.com/ladybug-tools/lbt-grasshopper/wiki/' \ + '1.4-Compatibility-Matrix' + + def __init__(self, config_file=None, mute=True): + self.mute = bool(mute) # set the mute value + self.config_file = config_file # load paths from the config JSON file + + @property + def mapper_path(self): + """Get or set the path to the Ruby mapper used in URBANopt workflows. + + This is the Ruby file that is used to map URBANopt geoJSON features to + honeybee model JSONs. + """ + return self._mapper_path + + @mapper_path.setter + def mapper_path(self, path): + if not path: # check the default installation location + path = self._find_mapper_path() + if path: # check that the mapper file exists in the path + assert os.path.isfile(path) and path.endswith('.rb'), \ + '{} is not a valid path to a Ruby mapper file.'.format(path) + self._mapper_path = path # set the mapper_path + if path and not self.mute: + print("Path to Mapper is set to: %s" % path) + + @property + def urbanopt_gemfile_path(self): + """Get or set the path to the Gemfile used in URBANopt workflows. + + Setting this can be used to test newer versions of URBANopt with upgraded + dependencies in the Gemfile. + """ + return self._urbanopt_gemfile_path + + @urbanopt_gemfile_path.setter + def urbanopt_gemfile_path(self, path): + if not path: # check the default installation location + path = self._find_urbanopt_gemfile_path() + if path: # check that the Gemfile exists at the path + assert os.path.isfile(path), \ + '{} is not a valid path to an URBANopt Gemfile.'.format(path) + self._urbanopt_gemfile_path = path # set the urbanopt_gemfile_path + if path and not self.mute: + print("Path to URBANopt Gemfile is set to: %s" % path) + + @property + def urbanopt_cli_path(self): + """Get or set the path to the path where URBANopt is installed. + + Setting this can be used to test newer versions of URBANopt. + """ + return self._urbanopt_cli_path + + @urbanopt_cli_path.setter + def urbanopt_cli_path(self, path): + if not path: # check the default installation location + path = self._find_urbanopt_cli_path() + if path: # check that the installation exists at the path + assert os.path.isdir(path), \ + '{} is not a valid path to an URBANopt installation.'.format(path) + self._urbanopt_cli_path = path # set the urbanopt_cli_path + self._urbanopt_env_path = None + self._urbanopt_version = None + self._urbanopt_version_str = None + self._docker_version = None + self._docker_version_str = None + if path and not self.mute: + print("Path to URBANopt CLI is set to: %s" % path) + + @property + def urbanopt_env_path(self): + """Get or set the path to the executable used to set the URBANopt environment. + """ + return self._urbanopt_env_path + + @urbanopt_env_path.setter + def urbanopt_env_path(self, path): + if path: # check that the file exists at the path + assert os.path.isfile(path), \ + '{} is not a valid path to an URBANopt env executable.'.format(path) + self._urbanopt_env_path = path # set the urbanopt_env_path + if path and not self.mute: + print("Path to URBANopt Environment executable is set to: %s" % path) + + @property + def urbanopt_version(self): + """Get a tuple for the version of URBANopt (eg. (0, 7, 1)). + + This will be None if the version could not be sensed or if no URBANopt + installation was found. + """ + if self._urbanopt_cli_path and self._urbanopt_version_str is None: + self._urbanopt_version_from_cli() + return self._urbanopt_version + + @property + def urbanopt_version_str(self): + """Get text for the full version of URBANopt (eg. "0.7.1"). + + This will be None if the version could not be sensed or if no URBANopt + installation was found. + """ + if self._urbanopt_cli_path and self._urbanopt_version_str is None: + self._urbanopt_version_from_cli() + return self._urbanopt_version_str + + @property + def reopt_assumptions_path(self): + """Get or set the path to the JSON file that contains base REopt assumptions. + """ + return self._reopt_assumptions_path + + @reopt_assumptions_path.setter + def reopt_assumptions_path(self, path): + if not path: # check the default installation location + path = self._find_reopt_assumptions_path() + if path: # check that the file exists at the path + assert os.path.isfile(path), \ + '{} is not a valid path to a REopt assumptions JSON.'.format(path) + self._reopt_assumptions_path = path # set the reopt_assumptions_path + if path and not self.mute: + print("Path to REopt assumptions is set to: %s" % path) + + @property + def docker_version(self): + """Get a tuple for the version of Docker installed (eg. (24, 0, 7)). + + This will be None if the version could not be sensed or if no Docker + installation was found. + """ + if self._docker_version_str is None: + self._docker_version_from_cli() + return self._docker_version + + @property + def docker_version_str(self): + """Get text for the full version of Docker (eg. "24.0.7"). + + This will be None if the version could not be sensed or if no Docker + installation was found. + """ + if self._docker_version_str is None: + self._docker_version_from_cli() + return self._docker_version_str + + @property + def config_file(self): + """Get or set the path to the config.json file from which folders are loaded. + + Setting this to None will result in using the config.json module included + in this package. + """ + return self._config_file + + @config_file.setter + def config_file(self, cfg): + if cfg is None: + cfg = os.path.join(os.path.dirname(__file__), 'config.json') + self._load_from_file(cfg) + self._config_file = cfg + +
    +[docs] + def generate_urbanopt_env_path(self): + """Run the URBANopt setup-env file to set this object's urbanopt_env_path.""" + # search for the file in its default location + home_folder = os.getenv('HOME') or os.path.expanduser('~') + env_file = os.path.join(home_folder, '.env_uo.bat') if os.name == 'nt' else \ + os.path.join(home_folder, '.env_uo.sh') + + if self.urbanopt_cli_path: # try to generate the env file + if os.name == 'nt': + env_setup = os.path.join(self.urbanopt_cli_path, 'setup-env.bat') + if not os.path.isfile(env_setup): + env_setup = os.path.join(self.urbanopt_cli_path, 'setup-env.ps1') + else: + env_setup = os.path.join(self.urbanopt_cli_path, 'setup-env.sh') + if os.path.isfile(env_setup): + if os.name == 'nt': # run the batch file on Windows + if env_setup.endswith('.bat'): + os.system(env_setup) + else: + cmds = ['powershell.exe', env_setup] + p = subprocess.Popen(cmds) + p.communicate() + else: # run the sell file on Mac or Linux + subprocess.check_call(['chmod', 'u+x', env_setup]) + subprocess.call(env_setup) + if os.path.isfile(env_file): + if os.name == 'nt': # remove the utf-8 encoding powershell does + with open(env_file, 'r') as inf: + env_data = inf.read().splitlines(True) + if not env_data[0] == '\n' and not env_data[0].startswith('SET'): + env_data = env_data[1:] + with open(env_file, 'w') as otf: + otf.write(''.join(env_data)) + self._urbanopt_env_path = env_file # the file was successfully generated
    + + +
    +[docs] + def check_urbanopt_version(self): + """Check if the installed version of URBANopt is the acceptable one.""" + in_msg = 'Get a compatible version of URBANopt by downloading and installing\n' \ + 'the version of URBANopt listed in the Ladybug Tools compatibility ' \ + 'matrix\n{}.'.format(self.COMPATIBILITY_URL) + assert self.urbanopt_cli_path is not None, \ + 'No URBANopt installation was found on this machine.\n{}'.format(in_msg) + uo_version = self.urbanopt_version + if uo_version is None: + if self.urbanopt_env_path is not None: + ext = '.bat' if os.name == 'nt' else '.sh' + ver_file = os.path.join( + os.path.dirname(self.urbanopt_env_path), + '.check_uo_version{}'.format(ext)) + process = subprocess.Popen(ver_file, stderr=subprocess.PIPE, shell=True) + _, stderr = process.communicate() + else: + stderr = 'Unable to set up the URBANopt environment.' + msg = 'An URBANopt installation was found at {}\n' \ + 'but the URBANopt executable is not accessible.\n{}'.format( + self.urbanopt_cli_path, stderr) + raise ValueError(msg) + assert uo_version[0] == self.URBANOPT_VERSION[0] and \ + uo_version[1] == self.URBANOPT_VERSION[1], \ + 'The installed URBANopt is version {}.\nMust be version {} to work ' \ + 'with dragonfly.\n{}'.format( + '.'.join(str(v) for v in uo_version), + '.'.join(str(v) for v in self.URBANOPT_VERSION), in_msg)
    + + + def _load_from_file(self, file_path): + """Set all of the the properties of this object from a config JSON file. + + Args: + file_path: Path to a JSON file containing the file paths. A sample of this + JSON is the config.json file within this package. + """ + # check the default file path + assert os.path.isfile(str(file_path)), \ + ValueError('No file found at {}'.format(file_path)) + + # set the default paths to be all blank + default_path = { + "mapper_path": r'', + "urbanopt_gemfile_path": r'', + "urbanopt_cli_path": r'', + "urbanopt_env_path": r'', + "reopt_assumptions_path": r'' + } + + with open(file_path, 'r') as cfg: + try: + paths = json.load(cfg) + except Exception as e: + print('Failed to load paths from {}.\n{}'.format(file_path, e)) + else: + for key, p in paths.items(): + if isinstance(key, list) or not key.startswith('__'): + try: + default_path[key] = p.strip() + except AttributeError: + default_path[key] = p + + # set paths for the configuration + self.mapper_path = default_path["mapper_path"] + self.urbanopt_gemfile_path = default_path["urbanopt_gemfile_path"] + self.urbanopt_cli_path = default_path["urbanopt_cli_path"] + self.urbanopt_env_path = default_path["urbanopt_env_path"] + self.reopt_assumptions_path = default_path["reopt_assumptions_path"] + + def _urbanopt_version_from_cli(self): + """Set this object's URBANopt version by making a call to URBANopt CLI.""" + if not self.urbanopt_env_path: + self.generate_urbanopt_env_path() + assert self.urbanopt_env_path is not None, 'Unable to set up the URBANopt ' \ + 'environment. Make sure it is installed correctly.' + if os.name == 'nt': + working_drive = self.urbanopt_env_path[:2] + batch = '{}\ncd {}\ncall {}\nuo --version'.format( + working_drive, working_drive, self.urbanopt_env_path) + batch_file = os.path.join( + os.path.dirname(self.urbanopt_env_path), '.check_uo_version.bat') + write_to_file(batch_file, batch, True) + process = subprocess.Popen(batch_file, stdout=subprocess.PIPE, shell=True) + stdout = process.communicate() + else: + shell = '#!/usr/bin/env bash\nsource {}\nuo --version'.format( + self.urbanopt_env_path) + shell_file = os.path.join( + os.path.dirname(self.urbanopt_env_path), '.check_uo_version.sh') + write_to_file(shell_file, shell, True) + # make the shell script executable using subprocess.check_call + subprocess.check_call(['chmod', 'u+x', shell_file]) + # run the shell script + process = subprocess.Popen(shell_file, stdout=subprocess.PIPE, shell=True) + stdout = process.communicate() + base_str = str(stdout[0]).split('--version')[-1] + base_str = base_str.replace(r"\r", '').replace(r"\n", '').replace(r"'", '') + base_str = base_str.strip() + try: + ver_nums = base_str.split('.') + self._urbanopt_version = tuple(int(i) for i in ver_nums) + self._urbanopt_version_str = base_str + except Exception: + pass # failed to parse the version into integers + + def _docker_version_from_cli(self): + """Set this object's Docker version by making a call to Docker CLI.""" + cmds = ['docker', '--version'] + use_shell = True if os.name == 'nt' else False + process = subprocess.Popen(cmds, stdout=subprocess.PIPE, shell=use_shell) + stdout = process.communicate() + base_str = str(stdout[0]).replace("b'", '').replace(r"\n'", '') + try: + self._docker_version_str = base_str.split(',')[0].split(' ')[-1] + ver_nums = self._docker_version_str.split('.') + self._docker_version = tuple(int(i) for i in ver_nums) + except Exception: + pass # failed to parse the version into integers + + @staticmethod + def _find_mapper_path(): + """Find the mapper that is distributed with the honeybee-openstudio-gem.""" + measure_install = hb_energy_config.folders.honeybee_openstudio_gem_path + if measure_install: + mapper_file = os.path.join(measure_install, 'files', 'Honeybee.rb') + if os.path.isfile(mapper_file): + return mapper_file + return None + + @staticmethod + def _find_urbanopt_gemfile_path(): + """Find the URBANopt Gemfile that's distributed with honeybee-openstudio-gem.""" + measure_install = hb_energy_config.folders.honeybee_openstudio_gem_path + if measure_install: + gem_file = os.path.join(measure_install, 'files', 'urbanopt_Gemfile') + if os.path.isfile(gem_file): + return gem_file + return None + + @staticmethod + def _find_reopt_assumptions_path(): + """Find the REopt assumptions that's distributed with honeybee-openstudio-gem.""" + measure_install = hb_energy_config.folders.honeybee_openstudio_gem_path + if measure_install: + reopt_file = os.path.join(measure_install, 'files', 'reopt_assumptions.json') + if os.path.isfile(reopt_file): + return reopt_file + return None + + @staticmethod + def _find_urbanopt_cli_path(): + """Find the most recent URBANopt CLI in its default location.""" + def getversion(urbanopt_path): + """Get digits for the version of OpenStudio.""" + try: + ver = ''.join(s for s in urbanopt_path if (s.isdigit() or s == '.')) + return sum(int(d) * (10 ** i) + for i, d in enumerate(reversed(ver.split('.')))) + except ValueError: # folder starting with 'openstudio' and no version + return 0 + + if os.name == 'nt': # search the C:/ drive on Windows + uo_folders = ['C:\\{}'.format(f) for f in os.listdir('C:\\') + if (f.lower().startswith('urbanopt') and + os.path.isdir('C:\\{}'.format(f)))] + elif platform.system() == 'Darwin': # search the Applications folder on Mac + uo_folders = \ + ['/Applications/{}'.format(f) for f in os.listdir('/Applications/') + if (f.lower().startswith('urbanopt') and + os.path.isdir('/Applications/{}'.format(f)))] + elif platform.system() == 'Linux': # search the usr/local folder + uo_folders = ['/usr/local/{}'.format(f) for f in os.listdir('/usr/local/') + if (f.lower().startswith('urbanopt') and + os.path.isdir('/usr/local/{}'.format(f)))] + else: # unknown operating system + uo_folders = None + + if not uo_folders: # No Openstudio installations were found + return None + + # get the most recent version of OpenStudio that was found + uo_path = sorted(uo_folders, key=getversion, reverse=True)[0] + return uo_path
    + + + +"""Object possesing all key folders within the configuration.""" +folders = Folders(mute=True) +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/des/connector.html b/docs/_modules/dragonfly_energy/des/connector.html new file mode 100644 index 00000000..c00bc823 --- /dev/null +++ b/docs/_modules/dragonfly_energy/des/connector.html @@ -0,0 +1,1161 @@ + + + + + + + dragonfly_energy.des.connector — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.des.connector

    +# coding=utf-8
    +"""Thermal connector in a District Energy System."""
    +from __future__ import division
    +
    +from .._base import _GeometryBase
    +
    +from ladybug_geometry.geometry2d.line import LineSegment2D
    +from ladybug_geometry.geometry2d.polyline import Polyline2D
    +from dragonfly.projection import polygon_to_lon_lat
    +
    +
    +
    +[docs] +class ThermalConnector(_GeometryBase): + """Represents a thermal connector carrying hot, chilled or ambient water in a DES. + + Args: + identifier: Text string for a unique thermal connector ID. Must contain only + characters that are acceptable in a DES. This will be used to + identify the object across the exported geoJSON and DES files. + geometry: A LineSegment2D or Polyline2D representing the geometry of the + thermal connector. + + Properties: + * identifier + * display_name + * geometry + """ + __slots__ = () + + def __init__(self, identifier, geometry): + """Initialize ThermalConnector.""" + _GeometryBase.__init__(self, identifier) # process the identifier + assert isinstance(geometry, (LineSegment2D, Polyline2D)), 'Expected ' \ + 'ladybug_geometry LineSegment2D or Polyline2D. Got {}'.format(type(geometry)) + self._geometry = geometry + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize an ThermalConnector from a dictionary. + + Args: + data: A dictionary representation of an ThermalConnector object. + """ + # check the type of dictionary + assert data['type'] == 'ThermalConnector', 'Expected ThermalConnector ' \ + 'dictionary. Got {}.'.format(data['type']) + geo = LineSegment2D.from_dict(data['geometry']) \ + if data['geometry']['type'] == 'LineSegment2D' \ + else Polyline2D.from_dict(data['geometry']) + con = cls(data['identifier'], geo) + if 'display_name' in data and data['display_name'] is not None: + con.display_name = data['display_name'] + return con
    + + +
    +[docs] + @classmethod + def from_dict_abridged(cls, data): + """Initialize an ThermalConnector from an abridged dictionary. + + Args: + data: A ThermalConnector dictionary. + """ + return cls.from_dict(data)
    + + +
    +[docs] + @classmethod + def from_geojson_dict( + cls, data, origin_lon_lat, conversion_factors): + """Get a ThermalConnector from a dictionary as it appears in a GeoJSON. + + Args: + data: A GeoJSON dictionary representation of an ThermalConnector feature. + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + geo = cls._geojson_coordinates_to_line2d( + data['geometry']['coordinates'], origin_lon_lat, conversion_factors) + return cls(data['properties']['id'], geo)
    + + + @property + def geometry(self): + """Get a LineSegment2D or Polyline2D representing the thermal connector.""" + return self._geometry + +
    +[docs] + def reverse(self): + """Reverse the direction of this object's geometry. + + This is useful when trying to orient the connector to the direction + of flow within a larger loop. + """ + self._geometry = self._geometry.flip() \ + if isinstance(self._geometry, LineSegment2D) else self._geometry.reverse()
    + + +
    +[docs] + def to_dict(self): + """ThermalConnector dictionary representation.""" + base = {'type': 'ThermalConnector'} + base['identifier'] = self.identifier + base['geometry'] = self.geometry.to_dict() + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, start_id, end_id, origin_lon_lat, conversion_factors, + start_feature_id=None, end_feature_id=None): + """Get ThermalConnector dictionary as it appears in an URBANopt geoJSON. + + Args: + start_id: Identifier of the junction at the start of the pipe. + end_id: Identifier of the junction at the end of the pipe. + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + start_feature_id: Optional identifier for a feature (Building or GHE field) + at the start of the pipe. + end_feature_id: Optional identifier for a feature (Building or GHE field) + at the end of the pipe. + """ + # translate the geometry coordinates to latitude and longitude + if isinstance(self.geometry, LineSegment2D): + pts = [(pt.x, pt.y) for pt in (self.geometry.p1, self.geometry.p2)] + else: # it's a polyline + pts = [(pt.x, pt.y) for pt in self.geometry.vertices] + coords = polygon_to_lon_lat(pts, origin_lon_lat, conversion_factors) + # assign all of the properties to the connector + conn_props = { + 'id': self.identifier, + 'type': 'ThermalConnector', + 'name': self.display_name, + 'startJunctionId': start_id, + 'endJunctionId': end_id, + 'total_length': round(self.geometry.length, 2), + 'connector_type': 'OnePipe', + 'fluid_temperature_type': 'Ambient', + 'flow_direction': 'Unspecified' + + } + if start_feature_id is not None: + conn_props['startFeatureId'] = start_feature_id + if end_feature_id is not None: + conn_props['endFeatureId'] = end_feature_id + # return the full dictionary + return { + 'type': 'Feature', + 'properties': conn_props, + 'geometry': { + 'type': 'LineString', + 'coordinates': coords + } + }
    + + + def __copy__(self): + new_con = ThermalConnector(self.identifier, self.geometry) + new_con._display_name = self._display_name + return new_con + + def __repr__(self): + return 'ThermalConnector: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/des/ghe.html b/docs/_modules/dragonfly_energy/des/ghe.html new file mode 100644 index 00000000..52d88796 --- /dev/null +++ b/docs/_modules/dragonfly_energy/des/ghe.html @@ -0,0 +1,2218 @@ + + + + + + + dragonfly_energy.des.ghe — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.des.ghe

    +# coding=utf-8
    +"""Ground Heat Exchanger (GHE) in a district thermal system."""
    +import math
    +import json
    +
    +from ladybug_geometry.geometry2d import Vector2D, Point2D, Polygon2D
    +from ladybug_geometry.geometry3d import Point3D, Vector3D, Plane, Face3D
    +from honeybee.typing import valid_string, float_positive, float_in_range, int_in_range
    +from honeybee.units import conversion_factor_to_meters
    +from honeybee.altnumber import autocalculate
    +from dragonfly.projection import polygon_to_lon_lat
    +
    +from .._base import _GeometryBase
    +
    +
    +
    +[docs] +class GroundHeatExchanger(_GeometryBase): + """Represents a Ground Heat Exchanger in a district thermal system. + + Args: + identifier: Text string for a unique heat exchanger ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + geometry: A Polygon2D or horizontal Face3D representing the geometry + of the heat exchanger. + + Properties: + * identifier + * display_name + * geometry + * boundary_2d + * holes_2d + """ + # a list of GHE properties that are needed to represent the GHE in EnergyPlus + PROPERTY_NAMES = ( + 'Borehole Length (m)', + 'Borehole Radius (m)', + 'Design Flow Rate (m3/s)', + 'Ground Temperature (C)', + 'Ground Conductivity (W/m-K)', + 'Ground Heat Capacity (J/m3-K)', + 'Grout Conductivity (W/m-K)', + 'Number of Boreholes', + 'Pipe Outer Diameter (m)', + 'Pipe Conductivity (W/m-K)', + 'Pipe Thickness (m)', + 'U Tube Distance (m)' + ) + # a list of corresponding fields in the GHEDesigner summary JSON + PROPERTY_PATHS = ( + ('ghe_system', 'active_borehole_length', 'value'), + ('ghe_system', 'borehole_diameter', 'value'), + ('ghe_system', 'fluid_mass_flow_rate_per_borehole', 'value'), + ('ghe_system', 'soil_undisturbed_ground_temp', 'value'), + ('ghe_system', 'soil_thermal_conductivity', 'value'), + ('ghe_system', 'soil_volumetric_heat_capacity', 'value'), + ('ghe_system', 'grout_thermal_conductivity', 'value'), + ('ghe_system', 'total_drilling', 'value'), + ('ghe_system', 'pipe_geometry', 'pipe_outer_diameter', 'value'), + ('ghe_system', 'pipe_thermal_conductivity', 'value'), + ('ghe_system', 'pipe_geometry', 'pipe_inner_diameter', 'value'), + ('ghe_system', 'shank_spacing', 'value') + ) + + __slots__ = () + + def __init__(self, identifier, geometry): + """Initialize GroundHeatExchanger.""" + _GeometryBase.__init__(self, identifier) # process the identifier + assert isinstance(geometry, (Polygon2D, Face3D)), 'Expected ladybug_geometry ' \ + 'Polygon2D or Face3D for GroundHeatExchanger geometry. ' \ + 'Got {}'.format(type(geometry)) + if isinstance(geometry, Face3D): + if geometry.normal.z < 0: # ensure upward-facing Face3D + geometry = geometry.flip() + # ensure a global 2D origin, which helps in solve adjacency and the dict schema + o_pl = Plane(Vector3D(0, 0, 1), Point3D(0, 0, geometry.plane.o.z)) + geometry = Face3D(geometry.boundary, o_pl, geometry.holes) + self._geometry = geometry + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize a GroundHeatExchanger from a dictionary. + + Args: + data: A dictionary representation of an GroundHeatExchanger object. + """ + # check the type of dictionary + assert data['type'] == 'GroundHeatExchanger', 'Expected GroundHeatExchanger ' \ + 'dictionary. Got {}.'.format(data['type']) + geo = Face3D.from_dict(data['geometry']) \ + if data['geometry']['type'] == 'Face3D' \ + else Polygon2D.from_dict(data['geometry']) + trans = cls(data['identifier'], geo) + if 'display_name' in data and data['display_name'] is not None: + trans.display_name = data['display_name'] + return trans
    + + +
    +[docs] + @classmethod + def from_geojson_dict( + cls, data, origin_lon_lat, conversion_factors): + """Get a GroundHeatExchanger from a dictionary as it appears in a GeoJSON. + + Args: + data: A GeoJSON dictionary representation of an GroundHeatExchanger feature. + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + geo = cls._geojson_coordinates_to_face3d( + data['geometry']['coordinates'], origin_lon_lat, conversion_factors) + return cls(data['properties']['id'], geo)
    + + + @property + def geometry(self): + """Get a Polygon2D or Face3D representing the ground heat exchanger.""" + return self._geometry + + @property + def boundary_2d(self): + """Get a Polygon2D for the outer boundary of the ground heat exchanger.""" + return self._geometry.boundary_polygon2d \ + if isinstance(self._geometry, Face3D) else self._geometry + + @property + def hole_polygon2d(self): + """Get a list of Polygon2D for the holes in the ground heat exchanger. + + Will be None if the ground heat exchanger has no holes in it. + """ + return self._geometry.hole_polygon2d \ + if isinstance(self._geometry, Face3D) else None + +
    +[docs] + def to_dict(self): + """GroundHeatExchanger dictionary representation.""" + base = {'type': 'GroundHeatExchanger'} + base['identifier'] = self.identifier + base['geometry'] = self.geometry.to_dict() + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, origin_lon_lat, conversion_factors): + """Get GroundHeatExchanger dictionary as it appears in an URBANopt geoJSON. + + Args: + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + if isinstance(self.geometry, Face3D): + loops = [[(pt.x, pt.y) for pt in self.geometry.boundary]] + if self.geometry.has_holes: + for hole in self.geometry.holes: + loops.append([(pt.x, pt.y) for pt in hole]) + else: + loops = [[(pt.x, pt.y) for pt in self.geometry.vertices]] + coords = [] + for pts in loops: + loop = polygon_to_lon_lat(pts, origin_lon_lat, conversion_factors) + loop.append(loop[0]) + coords.append(loop) + return { + 'type': 'Feature', + 'properties': { + 'id': self.identifier, + 'geometryType': 'Rectangle', + 'name': self.display_name, + 'type': 'District System', + 'footprint_area': round(self.geometry.area, 1), + 'footprint_perimeter': round(self.geometry.perimeter, 1), + 'floor_area': round(self.geometry.area, 1), + 'district_system_type': 'Ground Heat Exchanger', + }, + 'geometry': { + 'type': 'Polygon', + 'coordinates': coords + } + }
    + + +
    +[docs] + def load_boreholes(self, borehole_file, units='Meters', ortho_rotation=False): + """Load borehole positions for this GHE from a borehole file made by GHEDesigner. + + Args: + borehole_file: Full path to a BoreFieldData.csv produced by GHEDesigner + from this GroundHeatExchanger object. + units: The units system in which the geometry of this GroundHeatExchanger + object exists. This is used to convert between GHEDesigner's + native units of Meters over to the units system of this + GroundHeatExchanger object. (Default: Meters). + ortho_rotation: A boolean to note whether this GroundHeatExchanger + geometry was rotated to have it's right-angles align with the + coordinate system of GHEDesigner. This should be False when this + GroundHeatExchanger's geometry was directly translated to + GHEDesigner and should be True if the geometry was converted + to GeoJSON and then translated to a GeoJSON by the ThermalNetwork + package. (Default: False). + + Returns: + A list of Point2D for the position of each borehole in the ground heat + exchanger. These points should all be contained within the geometry + of this object. + """ + # load the borehole positions from the file + with open(borehole_file, 'r') as bf: + borehole_data = bf.readlines() + + # create the Point2D objects and format them for the units system + scale_fac = 1.0 / conversion_factor_to_meters(units) + bound_poly = self.boundary_2d + min_pt = bound_poly.min + ghe_boreholes = [] + for pt in borehole_data[1:]: + b_pt = Point2D(*(float(c) for c in pt.split(','))) + b_pt = b_pt.scale(scale_fac) + ghe_boreholes.append(b_pt) + move_vec_2d = Vector2D(min_pt.x, min_pt.y) + ghe_boreholes = [pt.move(move_vec_2d) for pt in ghe_boreholes] + + # sense if the geometry has a right angle and, if so, rotate it + if ortho_rotation: + if bound_poly.is_clockwise: + bound_poly = bound_poly.reverse() + # get the point of the polygon representing the lower left corner + pt_dists = [] + for i, point in enumerate(bound_poly): + pt_dists.append((min_pt.distance_to_point(point), i)) + sorted_i = [x for _, x in sorted(pt_dists, key=lambda pair: pair[0])] + origin_i = sorted_i[0] + origin = bound_poly[origin_i] + prev_pt = bound_poly[origin_i - 1] + next_pt = bound_poly[origin_i + 1] \ + if origin_i < len(bound_poly) - 1 else bound_poly[0] + # check if there is a need to rotate the polygon + if not (origin.x == min_pt.x and origin.y == min_pt.y): + vec_1, vec_2 = next_pt - origin, prev_pt - origin + if 89 < math.degrees(vec_1.angle(vec_2)) < 91: + # rotate all of the boreholes + y_axis = Vector2D(0, 1) + rot_ang = math.degrees(vec_2.angle_counterclockwise(y_axis)) + rot_ang = rot_ang - 360 if rot_ang > 180 else rot_ang + ghe_boreholes = [pt.rotate(math.radians(-rot_ang), origin) + for pt in ghe_boreholes] + return ghe_boreholes
    + + +
    +[docs] + @staticmethod + def load_g_function(g_func_file): + """Load the G-Function for this GHE from a G function file made by GHEDesigner. + + Args: + g_func_file: Full path to a Gfunction.csv produced by GHEDesigner + from this GroundHeatExchanger object. + + Returns: + A list of lists of G-function coefficients that describe the response + of the ground to the input loads. Each pair of factors represents + a point on the G-function. Flattening this list of lists yields + properties that can be plugged into the EnergyPlus G-function object. + """ + with open(g_func_file, 'r') as gf: + g_function = gf.readlines() + g_function = [[float(v) for v in line.split(',')[:2]] for line in g_function[1:]] + return g_function
    + + +
    +[docs] + @staticmethod + def load_energyplus_properties(summary_file): + """Load E+ properties for this GHE from a summary file made by GHEDesigner. + + Args: + summary_file: Full path to a SimulationSummary.json produced by GHEDesigner + from this GroundHeatExchanger object. + + Returns: + A list of properties of the ground heat exchanger that are needed to + simulate it in EnergyPlus. These values output here correspond to the + PROPERTY_NAMES on this object. + """ + with open(summary_file, 'r') as sf: + summary_data = json.load(sf) + properties = [] + zp = zip(GroundHeatExchanger.PROPERTY_NAMES, GroundHeatExchanger.PROPERTY_PATHS) + for p_name, p_path in zp: + val = summary_data[p_path[0]] + for key in p_path[1:]: + val = val[key] + if '(J/m3-K)' in p_name: + val = val * 0.001 + if 'Borehole Radius' in p_name: + val = val * 0.5 + if 'Number of Boreholes' in p_name: + val = int(val / properties[0]) + properties.append(val) + properties[-2] = properties[-4] - properties[-2] # pipe thickness from diameter + # compute total system flow rate from per-borehole rate + density = summary_data['ghe_system']['fluid_density']['value'] + properties[2] = (properties[2] * properties[7]) / density + return properties
    + + +
    +[docs] + @staticmethod + def load_monthly_temperatures(summary_file): + """Load ground temperatures for this GHE from a summary file made by GHEDesigner. + + Args: + summary_file: Full path to a SimulationSummary.json produced by GHEDesigner + from this GroundHeatExchanger object. + + Returns: + A list of ground temperatures in Celsius with one value for each month + of the period over which the GHEDesigner simulation was run (typically + 20 years). This can be used to check the drift in the ground temperature + over long periods of time. + """ + with open(summary_file, 'r') as sf: + sum_data = json.load(sf) + temperatures = [] + for month_data in sum_data['simulation_results']['monthly_temp_summary']['data']: + temperatures.append(month_data[1]) + return temperatures
    + + + def __copy__(self): + new_ghe = GroundHeatExchanger(self.identifier, self.geometry) + new_ghe._display_name = self._display_name + return new_ghe + + def __repr__(self): + return 'GroundHeatExchanger: {}'.format(self.display_name)
    + + + +
    +[docs] +class SoilParameter(object): + """Represents the soil properties within a ground heat exchanger field. + + Args: + conductivity: A number for the soil conductivity in W/m-K. (Default: 2.3). + heat_capacity: A number for the volumetric heat capacity of the soil + in J/m3-K. (Default: 2,343,500). + undisturbed_temperature: A number for the undisturbed annual average soil + temperature in degrees Celsius. If autocalculate, this value will + automatically be replaced with the average EPW temperature before + simulation. (Default: Autocalculate). + grout_conductivity: A number for the grout conductivity in W/m-K. (Default: 1.0). + grout_heat_capacity: A number for the volumetric heat capacity of the grout + in J/m3-K. (Default: 3,901,000). + + Properties: + * conductivity + * heat_capacity + * undisturbed_temperature + * grout_conductivity + * grout_heat_capacity + """ + + __slots__ = ('_conductivity', '_heat_capacity', '_undisturbed_temperature', + '_grout_conductivity', '_grout_heat_capacity') + + def __init__(self, conductivity=2.3, heat_capacity=2343500, + undisturbed_temperature=autocalculate, + grout_conductivity=1.0, grout_heat_capacity=3901000): + """Initialize SoilParameter.""" + self.conductivity = conductivity + self.heat_capacity = heat_capacity + self.undisturbed_temperature = undisturbed_temperature + self.grout_conductivity = grout_conductivity + self.grout_heat_capacity = grout_heat_capacity + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a SoilParameter object from a dictionary + + Args: + data: A dictionary representation of an SoilParameter object + in the format below. + + .. code-block:: python + + { + 'type': 'SoilParameter', + 'conductivity': 1.8, # float in W/m2-K + 'heat_capacity': 2100000, # float in J/m3-K + 'undisturbed_temperature': 18, # float in C or autocalculate + 'grout_conductivity': 1.0, # float in W/m2-K + 'grout_heat_capacity': 3901000 + } + """ + cond = data['conductivity'] if 'conductivity' in data else 2.3 + cap = data['heat_capacity'] if 'heat_capacity' in data else 2343500 + u_temp = autocalculate if 'undisturbed_temperature' not in data or \ + data['undisturbed_temperature'] == autocalculate.to_dict() \ + else data['undisturbed_temperature'] + g_cond = data['grout_conductivity'] if 'grout_conductivity' in data else 1.0 + g_cap = data['grout_heat_capacity'] if 'grout_heat_capacity' in data else 3901000 + return cls(cond, cap, u_temp, g_cond, g_cap)
    + + + @property + def conductivity(self): + """Get or set a number for the soil conductivity in W/m-K.""" + return self._conductivity + + @conductivity.setter + def conductivity(self, value): + self._conductivity = float_positive(value, 'soil conductivity') + + @property + def heat_capacity(self): + """Get or set a number for the volumetric heat capacity of the soil in J/m3-K.""" + return self._heat_capacity + + @heat_capacity.setter + def heat_capacity(self, value): + self._heat_capacity = float_positive(value, 'soil heat_capacity') + + @property + def undisturbed_temperature(self): + """Get or set an integer (or Autocalculate) for the vegetation end month.""" + return self._undisturbed_temperature if self._undisturbed_temperature \ + is not None else autocalculate + + @undisturbed_temperature.setter + def undisturbed_temperature(self, value): + if value == autocalculate: + self._undisturbed_temperature = None + else: + self._undisturbed_temperature = \ + float_in_range(value, -273, 200, 'undisturbed_temperature') + + @property + def grout_conductivity(self): + """Get or set a number for the grout conductivity in W/m-K.""" + return self._grout_conductivity + + @grout_conductivity.setter + def grout_conductivity(self, value): + self._grout_conductivity = float_positive(value, 'grout conductivity') + + @property + def grout_heat_capacity(self): + """Get or set a number for the volumetric heat capacity of the grout in J/m3-K. + """ + return self._grout_heat_capacity + + @grout_heat_capacity.setter + def grout_heat_capacity(self, value): + self._grout_heat_capacity = float_positive(value, 'grout heat_capacity') + +
    +[docs] + def to_dict(self): + """Get SoilParameter dictionary.""" + base = {'type': 'SoilParameter'} + base['conductivity'] = self.conductivity + base['heat_capacity'] = self.heat_capacity + if self._undisturbed_temperature is not None: + base['undisturbed_temperature'] = self._undisturbed_temperature + base['grout_conductivity'] = self.grout_conductivity + base['grout_heat_capacity'] = self.grout_heat_capacity + return base
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + new_obj = SoilParameter(self._conductivity, self._heat_capacity) + new_obj._undisturbed_temperature = self._undisturbed_temperature + new_obj._grout_conductivity = self._grout_conductivity + new_obj._grout_heat_capacity = self._grout_heat_capacity + return new_obj + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent SoilParameter.""" + return 'SoilParameter: [conductivity: {} W/m2-K] ' \ + '[heat capacity: {} J/m3-K]'.format(self._conductivity, self._heat_capacity)
    + + + +
    +[docs] +class FluidParameter(object): + """Represents the fluid properties within a ground heat exchanger field. + + Args: + fluid_type: Text to indicate the type of fluid circulating through the + ground heat exchanger loop. Choose from the options + below. (Default: Water). + + * Water + * EthylAlcohol + * EthyleneGlycol + * MethylAlcohol + * PropyleneGlycol + + concentration: A number between 0 and 60 for the concentration of the + fluid_type in water in percent. Note that this variable has no effect + when the fluid_type is Water. (Default: 35). + temperature: A number for the average design fluid temperature at peak + conditions in Celsius. (Default: 20). + + Properties: + * fluid_type + * concentration + * temperature + """ + + __slots__ = ('_fluid_type', '_concentration', '_temperature') + FLUID_TYPES = ( + 'Water', 'EthylAlcohol', 'EthyleneGlycol', 'MethylAlcohol', 'PropyleneGlycol') + + def __init__(self, fluid_type='Water', concentration=35, temperature=20): + """Initialize FluidParameter.""" + self.fluid_type = fluid_type + self.concentration = concentration + self.temperature = temperature + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a FluidParameter object from a dictionary + + Args: + data: A dictionary representation of an FluidParameter object + in the format below. + + .. code-block:: python + + { + 'type': 'FluidParameter', + 'fluid_type': 'PropyleneGlycol', # text for fluid_type + 'concentration': 33, # float for percentage concentration + 'temperature': 22 # float in C + } + """ + ft = data['fluid_type'] if 'fluid_type' in data else 'Water' + con = data['concentration'] if 'concentration' in data else 35 + temp = 20 if 'temperature' not in data else data['temperature'] + return cls(ft, con, temp)
    + + + @property + def fluid_type(self): + """Get or set text to indicate the type of fluid.""" + return self._fluid_type + + @fluid_type.setter + def fluid_type(self, value): + clean_input = valid_string(value).lower() + for key in self.FLUID_TYPES: + if key.lower() == clean_input: + value = key + break + else: + raise ValueError( + 'fluid_type {} is not recognized.\nChoose from the ' + 'following:\n{}'.format(value, self.FLUID_TYPES)) + self._fluid_type = value + + @property + def concentration(self): + """Get or set a number for the concentration of the fluid_type in water [%].""" + return self._concentration + + @concentration.setter + def concentration(self, value): + self._concentration = float_in_range(value, 0, 60, 'fluid concentration') + + @property + def temperature(self): + """Get or set a number for the average design fluid temperature in Celsius.""" + return self._temperature + + @temperature.setter + def temperature(self, value): + self._temperature = float_positive(value, 'fluid temperature') + +
    +[docs] + def to_dict(self): + """Get FluidParameter dictionary.""" + base = {'type': 'FluidParameter'} + base['fluid_type'] = self.fluid_type + base['concentration'] = self.concentration + base['temperature'] = self.temperature + return base
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + return FluidParameter(self._fluid_type, self._concentration, self._temperature) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent SoilParameter.""" + return 'FluidParameter: [fluid_type: {}] ' \ + '[concentration: {}%]'.format(self._fluid_type, self._concentration)
    + + + +
    +[docs] +class PipeParameter(object): + """Represents the pipe properties within a ground heat exchanger field. + + Args: + inner_diameter: A number for the diameter of the inner pipe surface in + meters. (Default: 0.0216). + outer_diameter: A number for the diameter of the outer pipe surface in + meters. (Default: 0.0266). + shank_spacing: A number for the spacing between the U-tube legs, as + referenced from outer surface of the pipes in meters. (NOT referenced + from each pipe's respective centerline). (Default: 0.0323). + roughness: A number for the linear dimension of bumps on the pipe surface + in meters. (Default: 1e-06) + conductivity: A number for the conductivity of the pipe material in + W/m-K. (Default: 0.4). + heat_capacity: A number for the volumetric heat capacity of the pipe + material in J/m3-K. (Default: 1,542,000). + arrangement: Text for the specified pipe arrangement. Choose from the + following options. (Default: SingleUTube). + + * SingleUTube + * DoubleUTubeSeries + * DoubleUTubeParallel + + Properties: + * inner_diameter + * outer_diameter + * shank_spacing + * roughness + * conductivity + * heat_capacity + * arrangement + """ + __slots__ = ('_inner_diameter', '_outer_diameter', '_shank_spacing', + '_roughness', '_conductivity', '_heat_capacity', '_arrangement') + ARRANGEMENT_TYPES = ('SingleUTube', 'DoubleUTubeSeries', 'DoubleUTubeParallel') + + def __init__( + self, inner_diameter=0.0216, outer_diameter=0.0266, shank_spacing=0.0323, + roughness=1e-06, conductivity=0.4, heat_capacity=1542000, + arrangement='SingleUTube'): + """Initialize PipeParameter.""" + self._inner_diameter = float_positive(inner_diameter, 'pipe inner_diameter') + self.outer_diameter = outer_diameter + self.shank_spacing = shank_spacing + self.roughness = roughness + self.conductivity = conductivity + self.heat_capacity = heat_capacity + self.arrangement = arrangement + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a PipeParameter object from a dictionary + + Args: + data: A dictionary representation of an PipeParameter object + in the format below. + + .. code-block:: python + + { + 'type': 'PipeParameter', + 'inner_diameter': 0.0216, # float for inner diameter in meters + 'outer_diameter': 0.0266 # float for outer diameter in meters + 'shank_spacing': 0.0323, # float for spacing between outer pipes in meters + 'roughness': 1e-06, # float for the dimension of the surface bumps + 'conductivity': 0.6, # float in W/m2-K + 'heat_capacity': 1542000, # float in J/m3-K + 'arrangement': 'SingleUTube' # text for arrangement type + } + """ + in_d = data['inner_diameter'] if 'inner_diameter' in data else 0.0216 + out_d = data['outer_diameter'] if 'outer_diameter' in data else 0.0266 + s_spc = data['shank_spacing'] if 'shank_spacing' in data else 0.0323 + rough = data['roughness'] if 'roughness' in data else 1e-06 + cond = data['conductivity'] if 'conductivity' in data else 2.3 + cap = data['heat_capacity'] if 'heat_capacity' in data else 2343500 + arr = data['arrangement'] if 'arrangement' in data else 'SingleUTube' + return cls(in_d, out_d, s_spc, rough, cond, cap, arr)
    + + + @property + def inner_diameter(self): + """Get or set a number for the inner diameter of the pipe in meters.""" + return self._inner_diameter + + @inner_diameter.setter + def inner_diameter(self, value): + self._inner_diameter = float_positive(value, 'pipe inner diameter') + self._diameter_check() + + @property + def outer_diameter(self): + """Get or set a number for the outer diameter of the pipe in meters.""" + return self._outer_diameter + + @outer_diameter.setter + def outer_diameter(self, value): + self._outer_diameter = float_positive(value, 'pipe outer diameter') + self._diameter_check() + + @property + def shank_spacing(self): + """Get or set a number for the shank spacing between the pipes in meters.""" + return self._shank_spacing + + @shank_spacing.setter + def shank_spacing(self, value): + self._shank_spacing = float_positive(value, 'pipe shank spacing') + + @property + def roughness(self): + """Get or set a number for the dimension of the pipe surface bumps in meters.""" + return self._roughness + + @roughness.setter + def roughness(self, value): + self._roughness = float_positive(value, 'pipe roughness') + + @property + def conductivity(self): + """Get or set a number for the conductivity of the pipe material in W/m-K.""" + return self._conductivity + + @conductivity.setter + def conductivity(self, value): + self._conductivity = float_positive(value, 'pipe conductivity') + + @property + def heat_capacity(self): + """Get or set a number for the volumetric heat capacity of the pipe in J/m3-K.""" + return self._heat_capacity + + @heat_capacity.setter + def heat_capacity(self, value): + self._heat_capacity = float_positive(value, 'pipe heat_capacity') + + @property + def arrangement(self): + """Get or set text for the pipe arrangement. + + Choose from the following options: + + * SingleUTube + * DoubleUTubeSeries + * DoubleUTubeParallel + """ + return self._arrangement + + @arrangement.setter + def arrangement(self, value): + clean_input = valid_string(value).lower() + for key in self.ARRANGEMENT_TYPES: + if key.lower() == clean_input: + value = key + break + else: + raise ValueError( + 'arrangement {} is not recognized.\nChoose from the ' + 'following:\n{}'.format(value, self.ARRANGEMENT_TYPES)) + self._arrangement = value + +
    +[docs] + def to_dict(self): + """Get PipeParameter dictionary.""" + base = {'type': 'PipeParameter'} + base['inner_diameter'] = self.inner_diameter + base['outer_diameter'] = self.outer_diameter + base['shank_spacing'] = self.shank_spacing + base['roughness'] = self.roughness + base['conductivity'] = self.conductivity + base['heat_capacity'] = self.heat_capacity + base['arrangement'] = self.arrangement + return base
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + return PipeParameter( + self.inner_diameter, self.outer_diameter, self.shank_spacing, + self.roughness, self.conductivity, self.heat_capacity, self.arrangement) + + def _diameter_check(self): + """Check that outer_diameter is greater than or equal to the inner_diameter.""" + assert self._outer_diameter > self._inner_diameter, \ + 'Pipe outer_diameter must be greater than or equal to inner_diameter.' + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent PipeParameter.""" + return 'PipeParameter: [diameter: {}m - {}m]'.format( + self.inner_diameter, self.outer_diameter)
    + + + +
    +[docs] +class BoreholeParameter(object): + """Represents the borehole properties within a ground heat exchanger field. + + Args: + min_depth: A number for the minimum depth of the heat-exchanging part + of the boreholes in meters. All boreholes will have a depth of + at least this value. So this typically represents the depth at which + borehole-drilling is most economical or the point at which it becomes + more cost effective to start a new borehole instead of making a given + borehole deeper. (Default: 60). + max_depth: A number for the maximum depth of the heat-exchanging part + of the boreholes in meters. When the system demand cannot be met + using boreholes with the min_depth, the boreholes will be extended + until either the loads or met or they reach this depth. So this + typically represents the depth of bedrock or the point at which + drilling deeper ceases to be practical. (Default: 135). + min_spacing: A number for the minimum spacing between boreholes in meters. + When the system demand cannot be met using boreholes with the max_spacing, + the borehole spacing will be reduced until either the loads or met + or they reach this spacing. So this typically represents the spacing + at which each borehole will interfere with neighboring ones so much + that it is not worthwhile to decrease the spacing further. (Default: 3). + max_spacing: A number for the maximum spacing between boreholes in meters. + All boreholes will have a spacing of at most this value. So this + typically represents the spacing at which the performance effects of + one borehole on a neighboring one are negligible. (Default: 25). + buried_depth: A number for the depth below the ground surface at which + the top of the heat exchanging part of the borehole sits in + meters. (Default: 2). + diameter: A number for the diameter of the borehole in meters. (Default: 0.15). + + Properties: + * min_depth + * max_depth + * min_spacing + * max_spacing + * buried_depth + * diameter + """ + __slots__ = ('_min_depth', '_max_depth', '_min_spacing', '_max_spacing', + '_buried_depth', '_diameter') + + def __init__(self, min_depth=60, max_depth=135, min_spacing=3, max_spacing=25, + buried_depth=2, diameter=0.15): + """Initialize BoreholeParameter.""" + self._min_depth = float_positive(min_depth, 'borehole min_depth') + self.max_depth = max_depth + self._min_spacing = float_positive(min_spacing, 'borehole min_spacing') + self.max_spacing = max_spacing + self.buried_depth = buried_depth + self.diameter = diameter + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a BoreholeParameter object from a dictionary + + Args: + data: A dictionary representation of an BoreholeParameter object + in the format below. + + .. code-block:: python + + { + 'type': 'BoreholeParameter', + 'min_depth': 30, # float in meters + 'max_depth': 90, # float in meters + 'min_spacing': 2.5, # float in meters + 'max_spacing': 8, # float in meters + 'buried_depth': 4, # float in meters + 'diameter': 0.2 # float in meters + } + """ + min_depth = data['min_depth'] if 'min_depth' in data else 60 + max_depth = data['max_depth'] if 'max_depth' in data else 135 + min_spacing = data['min_spacing'] if 'min_spacing' in data else 3 + max_spacing = data['max_spacing'] if 'max_spacing' in data else 10 + dth = data['buried_depth'] if 'buried_depth' in data else 2 + dia = data['diameter'] if 'diameter' in data else 0.15 + return cls(min_depth, max_depth, min_spacing, max_spacing, dth, dia)
    + + + @property + def min_depth(self): + """Get or set a number for the minimum depth of the borehole in meters.""" + return self._min_depth + + @min_depth.setter + def min_depth(self, value): + self._min_depth = float_positive(value, 'borehole min_depth') + self._depth_check() + + @property + def max_depth(self): + """Get or set a number for the maximum depth of the borehole in meters.""" + return self._max_depth + + @max_depth.setter + def max_depth(self, value): + self._max_depth = float_positive(value, 'borehole max_depth') + self._depth_check() + + @property + def min_spacing(self): + """Get or set a number for the minimum spacing between boreholes in m. + """ + return self._min_spacing + + @min_spacing.setter + def min_spacing(self, value): + self._min_spacing = float_positive(value, 'borehole min_spacing') + self._spacing_check() + + @property + def max_spacing(self): + """Get or set a number for the maximum spacing between boreholes in m. + """ + return self._max_spacing + + @max_spacing.setter + def max_spacing(self, value): + self._max_spacing = float_positive(value, 'borehole max_spacing') + self._spacing_check() + + @property + def buried_depth(self): + """Get or set a number for the depth of the top of the borehole in meters.""" + return self._buried_depth + + @buried_depth.setter + def buried_depth(self, value): + self._buried_depth = float_positive(value, 'borehole buried_depth') + + @property + def diameter(self): + """Get or set a number for the diameter of the borehole in meters.""" + return self._diameter + + @diameter.setter + def diameter(self, value): + self._diameter = float_positive(value, 'borehole diameter') + +
    +[docs] + def to_dict(self): + """Get BoreholeParameter dictionary.""" + base = {'type': 'BoreholeParameter'} + base['min_depth'] = self.min_depth + base['max_depth'] = self.max_depth + base['min_spacing'] = self.min_spacing + base['max_spacing'] = self.max_spacing + base['buried_depth'] = self.buried_depth + base['diameter'] = self.diameter + return base
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + return BoreholeParameter( + self.min_depth, self.max_depth, self.min_spacing, self.max_spacing, + self.buried_depth, self.diameter) + + def _depth_check(self): + """Check that max_depth is greater than or equal to min_depth.""" + assert self._max_depth >= self._min_depth, \ + 'Borehole max_depth must be greater than or equal to min_depth.' + + def _spacing_check(self): + """Check that max_spacing is greater than or equal to min_spacing.""" + assert self._max_spacing >= self._min_spacing, \ + 'Borehole max_spacing must be greater than or equal to min_spacing.' + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent BoreholeParameter.""" + return 'BoreholeParameter: [depth: {}m - {}m] [spacing: {}m - {}m]'.format( + self.min_depth, self.max_depth, self.min_spacing, self.max_spacing)
    + + + +
    +[docs] +class GHEDesignParameter(object): + """Represents criteria used to design a ground heat exchanger. + + Args: + flow_rate: A number for the volumetric design flow rate through the + ground heat exchanger in L/s. The value specified will be either for + the entire system system or per-borehole flow rate depending on + the flow_type set. (Default: 0.2 L/s). + flow_type: Text to indicate whether the design volumetric flow rate set on + a per-borehole or system basis. Choose from the following + options. (Default: Borehole). + + * Borehole + * System + + max_eft: A number for the maximum heat pump entering fluid temperature + in Celsius. (Default: 35C). + min_eft: A number for the minimum heat pump entering fluid temperature + in Celsius. (Default: 5C). + month_count: An integer for the number of months over which the simulation + will be run in order to ensure stable ground temperature + conditions. (Default: 240). + + Properties: + * flow_rate + * flow_type + * max_eft + * min_eft + * month_count + """ + __slots__ = ('_flow_rate', '_flow_type', '_max_eft', '_min_eft', '_month_count') + FLOW_TYPES = ('Borehole', 'System') + + def __init__(self, flow_rate=0.2, flow_type='Borehole', max_eft=35, min_eft=5, + month_count=240): + """Initialize BoreholeParameter.""" + self.flow_rate = flow_rate + self.flow_type = flow_type + self._min_eft = float_positive(min_eft, 'GHE min entering fluid temperature') + self.max_eft = max_eft + self.month_count = month_count + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a GHEDesignParameter object from a dictionary + + Args: + data: A dictionary representation of an GHEDesignParameter object + in the format below. + + .. code-block:: python + + { + 'type': 'GHEDesignParameter', + 'flow_rate': 30, # float in L/s + 'flow_type': 'Borehole', # text for the type of object flow_rate references + 'max_eft': 35, # float for max entering fluid temperature in C + 'min_eft': 5, # float for min entering fluid temperature in C + 'month_count': 240 # int for the number of months to run the simulation + } + """ + flow_rate = data['flow_rate'] if 'flow_rate' in data else 0.2 + flow_type = data['flow_type'] if 'flow_type' in data else 'Borehole' + max_eft = data['max_eft'] if 'max_eft' in data else 35 + min_eft = data['min_eft'] if 'min_eft' in data else 5 + month_count = data['month_count'] if 'month_count' in data else 240 + return cls(flow_rate, flow_type, max_eft, min_eft, month_count)
    + + + @property + def flow_rate(self): + """Get or set a number the volumetric design flow rate in L/s.""" + return self._flow_rate + + @flow_rate.setter + def flow_rate(self, value): + self._flow_rate = float_positive(value, 'ground heat exchanger flow_rate') + + @property + def flow_type(self): + """Get or set text for the type of object flow_rate references. + + Choose from the following options: + + * Borehole + * System + """ + return self._flow_type + + @flow_type.setter + def flow_type(self, value): + clean_input = valid_string(value).lower() + for key in self.FLOW_TYPES: + if key.lower() == clean_input: + value = key + break + else: + raise ValueError( + 'Flow type {} is not recognized.\nChoose from the ' + 'following:\n{}'.format(value, self.FLOW_TYPES)) + self._flow_type = value + + @property + def min_eft(self): + """Get or set a number for the minimum entering fluid temperature in Celsius.""" + return self._min_eft + + @min_eft.setter + def min_eft(self, value): + self._min_eft = float_positive(value, 'GHE min entering fluid temperature') + self._eft_check() + + @property + def max_eft(self): + """Get or set a number for the maximum entering fluid temperature in Celsius.""" + return self._max_eft + + @max_eft.setter + def max_eft(self, value): + self._max_eft = float_positive(value, 'GHE max entering fluid temperature') + self._eft_check() + + @property + def month_count(self): + """Get or set a number for the maximum entering fluid temperature in Celsius.""" + return self._month_count + + @month_count.setter + def month_count(self, value): + self._month_count = int_in_range(value, 12, input_name='GHE month count') + +
    +[docs] + def to_dict(self): + """Get GHEDesignParameter dictionary.""" + base = {'type': 'GHEDesignParameter'} + base['flow_rate'] = self.flow_rate + base['flow_type'] = self.flow_type + base['min_eft'] = self.min_eft + base['max_eft'] = self.max_eft + base['month_count'] = self.month_count + return base
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + return GHEDesignParameter( + self.flow_rate, self.flow_type, self.min_eft, self.max_eft, self.month_count) + + def _eft_check(self): + """Check that max_eft is greater than or equal to min_eft.""" + assert self._max_eft >= self._min_eft, \ + 'GHE max_eft must be greater than or equal to min_eft.' + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent GHEDesignParameter.""" + return 'GHEDesignParameter: [flow: {}L/s] [eft: {}C - {}C]'.format( + self.flow_rate, self.min_eft, self.max_eft)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/des/junction.html b/docs/_modules/dragonfly_energy/des/junction.html new file mode 100644 index 00000000..5a99ac59 --- /dev/null +++ b/docs/_modules/dragonfly_energy/des/junction.html @@ -0,0 +1,1095 @@ + + + + + + + dragonfly_energy.des.junction — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.des.junction

    +# coding=utf-8
    +"""Thermal junction in a District Energy System (DES)."""
    +from __future__ import division
    +
    +from .._base import _GeometryBase
    +
    +from ladybug_geometry.geometry2d.pointvector import Point2D
    +from honeybee.typing import valid_ep_string
    +from dragonfly.projection import polygon_to_lon_lat
    +
    +
    +
    +[docs] +class ThermalJunction(_GeometryBase): + """Represents an thermal junction connecting two objects in a DES. + + Args: + identifier: Text string for a unique thermal junction ID. Must contain only + characters that are acceptable in a DED. This will be used to + identify the object across the exported geoJSON and DES files. + geometry: A LineSegment2D or Polyline2D representing the geometry of the + thermal junction. + system_identifier: An optional text string for the identifier of a district + system object associated with the junction. District system objects + include Ground Heat Exchangers. (Default: None). + building_identifier: An optional text string for the identifier of a Building + object associated with the junction. (Default: None). + + Properties: + * identifier + * display_name + * geometry + * system_identifier + * building_identifier + """ + __slots__ = ('_system_identifier', '_building_identifier') + + def __init__(self, identifier, geometry, system_identifier=None, + building_identifier=None): + """Initialize ThermalJunction.""" + _GeometryBase.__init__(self, identifier) # process the identifier + assert isinstance(geometry, Point2D), 'Expected ladybug_geometry ' \ + 'Point2D for ThermalJunction. Got {}'.format(type(geometry)) + self._geometry = geometry + self.system_identifier = system_identifier + self.building_identifier = building_identifier + + @property + def geometry(self): + """Get a Point2D representing the ThermalJunction.""" + return self._geometry + + @property + def system_identifier(self): + """Get or set a text string for the ID of a Transformer or Substation.""" + return self._system_identifier + + @system_identifier.setter + def system_identifier(self, value): + self._system_identifier = valid_ep_string(value, 'system_identifier') \ + if value is not None else None + + @property + def building_identifier(self): + """Get or set a text string for the ID of a dragonfly Building.""" + return self._building_identifier + + @building_identifier.setter + def building_identifier(self, value): + self._building_identifier = valid_ep_string(value, 'building_identifier') \ + if value is not None else None + +
    +[docs] + def to_geojson_dict(self, origin_lon_lat, conversion_factors): + """Get an ThermalJunction dictionary as it appears in an URBANopt geoJSON. + + Args: + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + pt = (self.geometry.x, self.geometry.y) + coord = polygon_to_lon_lat([pt], origin_lon_lat, conversion_factors)[0] + geo_dict = { + 'type': 'Feature', + 'properties': { + 'id': self.identifier, + 'type': 'ThermalJunction', + 'junction_type': 'DES', + 'connection_type': 'Series' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': coord + } + } + if self._system_identifier is not None: + geo_dict['properties']['DSId'] = self._system_identifier + if self._building_identifier is not None: + geo_dict['properties']['buildingId'] = self._building_identifier + return geo_dict
    + + + def __copy__(self): + new_jct = ThermalJunction( + self.identifier, self.geometry, self._system_identifier, + self._building_identifier) + new_jct._display_name = self._display_name + return new_jct + + def __repr__(self): + return 'ThermalJunction: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/des/loop.html b/docs/_modules/dragonfly_energy/des/loop.html new file mode 100644 index 00000000..40e4feb0 --- /dev/null +++ b/docs/_modules/dragonfly_energy/des/loop.html @@ -0,0 +1,2335 @@ + + + + + + + dragonfly_energy.des.loop — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.des.loop

    +# coding=utf-8
    +"""Thermal Loop of a District Energy System (DES)."""
    +import os
    +import uuid
    +import json
    +
    +from ladybug_geometry.geometry2d import Point2D, LineSegment2D, Polyline2D, Polygon2D
    +from ladybug.location import Location
    +from ladybug.datacollection import HourlyContinuousCollection
    +from honeybee.typing import valid_ep_string, float_in_range
    +from honeybee.units import conversion_factor_to_meters
    +from dragonfly.projection import meters_to_long_lat_factors, \
    +    origin_long_lat_from_location
    +
    +from .ghe import GroundHeatExchanger, SoilParameter, FluidParameter, \
    +    PipeParameter, BoreholeParameter, GHEDesignParameter
    +from .connector import ThermalConnector
    +from .junction import ThermalJunction
    +
    +
    +
    +[docs] +class GHEThermalLoop(object): + """Represents an Ground Heat Exchanger Thermal Loop in a DES. + + This includes a GroundHeatExchanger and all thermal connectors needed + to connect these objects to Dragonfly Buildings in a loop. + + Args: + identifier: Text string for a unique thermal loop ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + ground_heat_exchangers: An array of GroundHeatExchanger objects representing + the fields of boreholes that supply the loop with thermal capacity. + connectors: An array of ThermalConnector objects that are included + within the thermal loop. In order for a given connector to be + valid within the loop, each end of the connector must touch either + another connector, a building footprint, or the ground_heat_exchangers. In + order for the loop as a whole to be valid, the connectors must form a + single continuous loop when passed through the buildings and the heat + exchanger field. + clockwise_flow: A boolean to note whether the direction of flow through the + loop is clockwise (True) when viewed from above in the GeoJSON or it + is counterclockwise (False). (Default: False). + soil_parameters: Optional SoilParameter object to specify the properties + of the soil in which the loop is operating. If None, default + values will be used. (Default: None). + fluid_parameters: Optional FluidParameter object to specify the properties + of the fluid that is circulating through the loop. If None, default + values will be used. (Default: None). + pipe_parameters: Optional PipeParameter object to specify the properties + of the ground-heat-exchanging pipes used across the loop. If None, + default values will be used. (Default: None). + borehole_parameters: Optional BoreholeParameter object to specify the + properties of the boreholes used across the loop. If None, + default values will be used. (Default: None). + design_parameters: Optional GHEDesignParameter object to specify the + design constraints across the loop. If None, default values + will be used. (Default: None). + + Properties: + * identifier + * display_name + * ground_heat_exchangers + * connectors + * clockwise_flow + * soil_parameters + * fluid_parameters + * pipe_parameters + * borehole_parameters + * design_parameters + """ + __slots__ = ( + '_identifier', '_display_name', '_ground_heat_exchangers', '_connectors', + '_clockwise_flow', '_soil_parameters', '_fluid_parameters', '_pipe_parameters', + '_borehole_parameters', '_design_parameters') + + def __init__(self, identifier, ground_heat_exchangers, connectors, + clockwise_flow=False, soil_parameters=None, fluid_parameters=None, + pipe_parameters=None, borehole_parameters=None, design_parameters=None): + """Initialize GHEThermalLoop.""" + self.identifier = identifier + self._display_name = None + self.ground_heat_exchangers = ground_heat_exchangers + self.connectors = connectors + self.clockwise_flow = clockwise_flow + self.soil_parameters = soil_parameters + self.fluid_parameters = fluid_parameters + self.pipe_parameters = pipe_parameters + self.borehole_parameters = borehole_parameters + self.design_parameters = design_parameters + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize an GHEThermalLoop from a dictionary. + + Args: + data: A dictionary representation of an GHEThermalLoop object. + """ + # check the type of dictionary + assert data['type'] == 'GHEThermalLoop', 'Expected GHEThermalLoop ' \ + 'dictionary. Got {}.'.format(data['type']) + # re-serialize geometry objects + ghe = [GroundHeatExchanger.from_dict(g) for g in data['ground_heat_exchangers']] + conns = [ThermalConnector.from_dict(c) for c in data['connectors']] + clock = data['clockwise_flow'] if 'clockwise_flow' in data else False + soil = SoilParameter.from_dict(data['soil_parameters']) \ + if 'soil_parameters' in data else None + fluid = FluidParameter.from_dict(data['fluid_parameters']) \ + if 'fluid_parameters' in data else None + pipe = PipeParameter.from_dict(data['pipe_parameters']) \ + if 'pipe_parameters' in data else None + bore = BoreholeParameter.from_dict(data['borehole_parameters']) \ + if 'borehole_parameters' in data else None + des = GHEDesignParameter.from_dict(data['design_parameters']) \ + if 'design_parameters' in data else None + loop = cls(data['identifier'], ghe, conns, clock, soil, fluid, pipe, bore, des) + if 'display_name' in data and data['display_name'] is not None: + loop.display_name = data['display_name'] + return loop
    + + +
    +[docs] + @classmethod + def from_geojson( + cls, geojson_file_path, location=None, point=None, units='Meters', + clockwise_flow=False): + """Get an GHEThermalLoop from a dictionary as it appears in a GeoJSON. + + Args: + geojson_file_path: Text for the full path to the geojson file to load + as GHEThermalLoop. + location: An optional ladybug location object with longitude and + latitude data defining the origin of the geojson file. If None, + an attempt will be made to sense the location from the project + point in the GeoJSON (if it exists). If nothing is found, the + origin is autocalcualted as the bottom-left corner of the bounding + box of all building footprints in the geojson file. (Default: None). + point: A ladybug_geometry Point2D for where the location object exists + within the space of a scene. The coordinates of this point are + expected to be in the units input. If None, an attempt will be + made to sense the CAD coordinates from the GeoJSON if they + exist. If not found, they will default to (0, 0). + units: Text for the units system in which the model geometry + exists. Default: 'Meters'. Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + Note that this method assumes the point coordinates are in the + same units. + clockwise_flow: A boolean to note whether the direction of flow through the + loop is clockwise (True) when viewed from above in the GeoJSON or it + is counterclockwise (False). (Default: False). + """ + # parse the geoJSON into a dictionary + with open(geojson_file_path, 'r') as fp: + data = json.load(fp) + + # extract the CAD coordinates and location from the GeoJSON if they exist + if 'project' in data: + prd = data['project'] + if 'latitude' in prd and 'longitude' in prd and location is None: + location = Location(latitude=prd['latitude'], longitude=prd['longitude']) + if 'cad_coordinates' in prd and point is None: + point = Point2D(*prd['cad_coordinates']) + if point is None: # just use the world origin if no point was found + point = Point2D(0, 0) + + # Get the list of thermal connector and GHE data + connector_data, ghe_data = [], [] + for obj_data in data['features']: + if 'type' in obj_data['properties']: + if obj_data['properties']['type'] == 'ThermalConnector': + connector_data.append(obj_data) + elif obj_data['properties']['type'] == 'District System' and \ + obj_data['properties']['district_system_type'] == \ + 'Ground Heat Exchanger': + ghe_data.append(obj_data) + + # if model units is not Meters, convert non-meter user inputs to meters + scale_to_meters = conversion_factor_to_meters(units) + if units != 'Meters': + point = point.scale(scale_to_meters) + + # Get long and lat in the geojson that correspond to the model origin (point). + # If location is None, derive coordinates from the geojson geometry. + if location is None: + point_lon_lat = cls._bottom_left_coordinate_from_geojson(connector_data) + location = Location(longitude=point_lon_lat[0], latitude=point_lon_lat[1]) + + # The model point may not be at (0, 0), so shift the longitude and latitude to + # get the equivalent point in longitude and latitude for (0, 0) in the model. + origin_lon_lat = origin_long_lat_from_location(location, point) + _convert_facs = meters_to_long_lat_factors(origin_lon_lat) + convert_facs = 1 / _convert_facs[0], 1 / _convert_facs[1] + + # extract the connectors + connectors = [] + for con_data in connector_data: + con_obj = ThermalConnector.from_geojson_dict( + con_data, origin_lon_lat, convert_facs) + connectors.append(con_obj) + # extract the substation + ghe_field = GroundHeatExchanger.from_geojson_dict( + ghe_data, origin_lon_lat, convert_facs) + + # create the loop and adjust for the units + base_name = os.path.basename(geojson_file_path) + loop_id = base_name.replace('.json', '').replace('.geojson', '') + loop = cls(loop_id, ghe_field, connectors, clockwise_flow) + if units != 'Meters': + loop.convert_to_units(units) + return loop
    + + + @staticmethod + def _bottom_left_coordinate_from_geojson(connector_data): + """Calculate the bottom-left bounding box coordinate from geojson coordinates. + + Args: + connector_data: a list of dictionaries containing geojson geometries that + represent thermal connectors. + + Returns: + The bottom-left most corner of the bounding box around the coordinates. + """ + xs, ys = [], [] + for conn in connector_data: + conn_coords = conn['geometry']['coordinates'] + if conn['geometry']['type'] == 'LineString': + for pt in conn_coords: + xs.append(pt[0]) + ys.append(pt[1]) + return min(xs), min(ys) + + @property + def identifier(self): + """Get or set the text string for unique object identifier.""" + return self._identifier + + @identifier.setter + def identifier(self, identifier): + self._identifier = valid_ep_string(identifier, 'identifier') + + @property + def display_name(self): + """Get or set a string for the object name without any character restrictions. + + If not set, this will be equal to the identifier. + """ + if self._display_name is None: + return self._identifier + return self._display_name + + @display_name.setter + def display_name(self, value): + try: + self._display_name = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._display_name = value # keep it as unicode + + @property + def ground_heat_exchangers(self): + """Get or set a tuple of GroundHeatExchanger objects for the loop's GHEs. + """ + return self._ground_heat_exchangers + + @ground_heat_exchangers.setter + def ground_heat_exchangers(self, values): + try: + if not isinstance(values, tuple): + values = tuple(values) + except TypeError: + raise TypeError( + 'Expected list or tuple for thermal loop ground_heat_exchangers. ' + 'Got {}'.format(type(values))) + for g in values: + assert isinstance(g, GroundHeatExchanger), 'Expected GroundHeatExchanger ' \ + 'object for thermal loop ground_heat_exchangers. Got {}.'.format(type(g)) + assert len(values) > 0, 'ThermalLoop must possess at least one GHE.' + self._ground_heat_exchangers = values + + @property + def connectors(self): + """Get or set the list of ThermalConnector objects within the loop.""" + return self._connectors + + @connectors.setter + def connectors(self, values): + try: + if not isinstance(values, tuple): + values = tuple(values) + except TypeError: + raise TypeError('Expected list or tuple for thermal loop connectors. ' + 'Got {}'.format(type(values))) + for c in values: + assert isinstance(c, ThermalConnector), 'Expected ThermalConnector ' \ + 'object for thermal loop connectors. Got {}.'.format(type(c)) + assert len(values) > 0, 'ThermalLoop must possess at least one connector.' + self._connectors = values + + @property + def clockwise_flow(self): + """Get or set a boolean for whether the flow through the loop is clockwise.""" + return self._clockwise_flow + + @clockwise_flow.setter + def clockwise_flow(self, value): + self._clockwise_flow = bool(value) + + @property + def soil_parameters(self): + """Get or set a SoilParameter object for the heat exchanger field.""" + return self._soil_parameters + + @soil_parameters.setter + def soil_parameters(self, value): + if value is None: + value = SoilParameter() + assert isinstance(value, SoilParameter), \ + 'Expected SoilParameter object' \ + ' for GroundHeatExchanger. Got {}.'.format(type(value)) + self._soil_parameters = value + + @property + def fluid_parameters(self): + """Get or set a FluidParameter object for the heat exchanger field.""" + return self._fluid_parameters + + @fluid_parameters.setter + def fluid_parameters(self, value): + if value is None: + value = FluidParameter() + assert isinstance(value, FluidParameter), \ + 'Expected FluidParameter object' \ + ' for GroundHeatExchanger. Got {}.'.format(type(value)) + self._fluid_parameters = value + + @property + def pipe_parameters(self): + """Get or set a PipeParameter object for the heat exchanger field.""" + return self._pipe_parameters + + @pipe_parameters.setter + def pipe_parameters(self, value): + if value is None: + value = PipeParameter() + assert isinstance(value, PipeParameter), \ + 'Expected PipeParameter object' \ + ' for GroundHeatExchanger. Got {}.'.format(type(value)) + self._pipe_parameters = value + + @property + def borehole_parameters(self): + """Get or set a BoreholeParameter object for the heat exchanger field.""" + return self._borehole_parameters + + @borehole_parameters.setter + def borehole_parameters(self, value): + if value is None: + value = BoreholeParameter() + assert isinstance(value, BoreholeParameter), \ + 'Expected BoreholeParameter object' \ + ' for GroundHeatExchanger. Got {}.'.format(type(value)) + self._borehole_parameters = value + + @property + def design_parameters(self): + """Get or set a GHEDesignParameter object for the heat exchanger field.""" + return self._design_parameters + + @design_parameters.setter + def design_parameters(self, value): + if value is None: + value = GHEDesignParameter() + assert isinstance(value, GHEDesignParameter), \ + 'Expected GHEDesignParameter object' \ + ' for GroundHeatExchanger. Got {}.'.format(type(value)) + self._design_parameters = value + +
    +[docs] + def junctions(self, tolerance=0.01): + """Get a list of ThermalJunction objects for the unique thermal loop junctions. + + The resulting ThermalJunction objects will be associated with the loop's + GroundHeatExchanger if they are in contact with it (within the tolerance). + However, they won't have any building_identifier associated with them. + The assign_junction_buildings method on this object can be used + to associate the junctions with an array of Dragonfly Buildings. + + Args: + tolerance: The minimum difference between the coordinate values of two + faces at which they can be considered centered adjacent. (Default: 0.01, + suitable for objects in meters). + + Returns: + A tuple with two items. + + - junctions - A list of lists of the unique ThermalJunction objects + that exist across the loop. + + - connector_junction_ids - A list of lists that align with the connectors + in the loop. Each sub-list contains two string values for the junction + IDs for each of the start and end of each of the connectors. + """ + return self._junctions_from_connectors(self.connectors, tolerance)
    + + +
    +[docs] + def loop_polygon(self, buildings, tolerance=0.01): + """Get a Polygon2D for the single continuous loop formed by connectors. + + This method will raise an exception if the ThermalConnectors do not form + a single continuous loop through the Buildings and the ground_heat_exchangers. + The Polygon2D will have the correct clockwise ordering according to this + object's clockwise_flow property. + + Args: + buildings: An array of Dragonfly Building objects in the same units + system as the GHEThermalLoop geometry. + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # get the footprints of the Buildings in 2D space and the GHE field + footprint_2d, bldg_ids = GHEThermalLoop._building_footprints( + buildings, tolerance) + for ghe in self.ground_heat_exchangers: + footprint_2d.append(ghe.boundary_2d) + bldg_ids.append(ghe.identifier) + + # determine which ThermalConnectors are linked to the buildings + feat_dict = {} + for bldg_poly, bldg_id in zip(footprint_2d, bldg_ids): + for conn in self.connectors: + c_p1, c_p2 = conn.geometry.p1, conn.geometry.p2 + p1_con = bldg_poly.is_point_on_edge(c_p1, tolerance) + p2_con = bldg_poly.is_point_on_edge(c_p2, tolerance) + if p1_con or p2_con: + rel_pt = c_p1 if p1_con else c_p2 + try: # assume that the first connection has been found + feat_dict[bldg_id].append(rel_pt) + except KeyError: # this is the first connection + feat_dict[bldg_id] = [rel_pt] + + # create a list with all line segment geometry in the loop + loop_segs = [] + for conn in self.connectors: + if isinstance(conn.geometry, LineSegment2D): + loop_segs.append(conn.geometry) + else: # assume that it is a PolyLine2D + loop_segs.extend(conn.geometry.segments) + for feat_id, f_pts in feat_dict.items(): + if len(f_pts) == 2: # valid connection with clear supply and return + loop_segs.append(LineSegment2D.from_end_points(f_pts[0], f_pts[1])) + elif len(f_pts) < 2: # only one connection; raise an error + msg = 'Feature "{}" contains only a single connection to a ' \ + 'ThermalConnector and cannot be integrated into a valid ' \ + 'loop.'.format(feat_id) + raise ValueError(msg) + else: # multiple connections; raise an error + msg = 'Feature "{}" contains {} connections to ThermalConnectors and ' \ + 'cannot be integrated into a valid loop.'.format(feat_id, len(f_pts)) + raise ValueError(msg) + + # join all of the segments together into a single polygon and set the order + loop_geos = Polyline2D.join_segments(loop_segs, tolerance) + assert len(loop_geos) == 1, 'A total of {} different loops were found across ' \ + 'all ThermalConnectors.\nOnly one loop is allowed.'.format(len(loop_geos)) + loop_geo = loop_geos[0] + assert loop_geo.is_closed(tolerance), 'The ThermalConnectors form an ' \ + 'open loop.\nThis loop must be closed in order to be valid.' + loop_poly = loop_geo.to_polygon(tolerance) + if loop_poly.is_clockwise is not self.clockwise_flow: + loop_poly = loop_poly.reverse() + + # make sure that the loop ends at a GHE; this is a limitation of GMT 0.8.0 + last_ghe_poly = self.ground_heat_exchangers[0].boundary_2d + for i_pt, pt in enumerate(loop_poly.vertices): + if last_ghe_poly.is_point_on_edge(pt, tolerance): + break_i = i_pt + 2 + break_i = break_i if break_i < len(loop_poly.vertices) \ + else break_i - len(loop_poly.vertices) + start_verts = loop_poly.vertices[break_i:] + loop_poly.vertices[:break_i] + loop_poly = Polygon2D(start_verts) + + return loop_poly
    + + +
    +[docs] + def ordered_connectors(self, buildings, tolerance=0.01): + """Get the ThermalConnectors of this GHEThermalLoop correctly ordered in a loop. + + The resulting connectors will not only be ordered correctly along the loop + but the orientation of the connector geometries will be property coordinated + with the clockwise_flow property on this object. + + This method will raise an exception if the ThermalConnectors do not form + a single continuous loop through the Buildings and the ground_heat_exchangers. + + Args: + buildings: An array of Dragonfly Building objects in the same units + system as the GHEThermalLoop geometry. + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # first get a Polygon2D for the continuous loop + loop_poly = self.loop_polygon(buildings, tolerance) + + # loop through the polygon segments and find each matching thermal connector + ord_conns, skip_count, tol = [], 0, tolerance + for loop_seg in loop_poly.segments: + if skip_count != 0: + skip_count -= 1 + continue + for conn in self.connectors: + if isinstance(conn.geometry, LineSegment2D) and \ + conn.geometry.is_equivalent(loop_seg, tol): + if not conn.geometry.p1.is_equivalent(loop_seg.p1, tol): + conn.reverse() + ord_conns.append(conn) + break + elif isinstance(conn.geometry, Polyline2D) and \ + (conn.geometry.p1.is_equivalent(loop_seg.p1, tol) or + conn.geometry.p2.is_equivalent(loop_seg.p1, tol)): + if not conn.geometry.p1.is_equivalent(loop_seg.p1, tol): + conn.reverse() + ord_conns.append(conn) + skip_count = len(conn.geometry.vertices) - 1 + break + return ord_conns
    + + +
    +[docs] + def move(self, moving_vec): + """Move this object along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the object. + """ + for ghe in self.ground_heat_exchangers: + ghe.move(moving_vec) + for connector in self.connectors: + connector.move(moving_vec)
    + + +
    +[docs] + def rotate_xy(self, angle, origin): + """Rotate this object counterclockwise in the XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + for ghe in self.ground_heat_exchangers: + ghe.rotate_xy(angle, origin) + for connector in self.connectors: + connector.rotate_xy(angle, origin)
    + + +
    +[docs] + def reflect(self, plane): + """Reflect this object across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will be reflected. + """ + for ghe in self.ground_heat_exchangers: + ghe.reflect(plane) + for connector in self.connectors: + connector.reflect(plane)
    + + +
    +[docs] + def scale(self, factor, origin=None): + """Scale this object by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + for ghe in self.ground_heat_exchangers: + ghe.scale(factor, origin) + for connector in self.connectors: + connector.scale(factor, origin)
    + + +
    +[docs] + def convert_to_units(self, units='Meters', starting_units='Meters'): + """Convert all of the geometry in this ThermalLoop to certain units. + + Args: + units: Text for the units to which the Model geometry should be + converted. (Default: Meters). Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + starting_units: The starting units system of the loop. (Default: Meters). + """ + if starting_units != units: + scale_fac1 = conversion_factor_to_meters(starting_units) + scale_fac2 = conversion_factor_to_meters(units) + scale_fac = scale_fac1 / scale_fac2 + self.scale(scale_fac)
    + + +
    +[docs] + def to_dict(self): + """GHEThermalLoop dictionary representation.""" + base = {'type': 'GHEThermalLoop'} + base['identifier'] = self.identifier + base['ground_heat_exchangers'] = \ + [g.to_dict() for g in self.ground_heat_exchangers] + base['connectors'] = [c.to_dict() for c in self.connectors] + base['clockwise_flow'] = self.clockwise_flow + base['soil_parameters'] = self.soil_parameters.to_dict() + base['fluid_parameters'] = self.fluid_parameters.to_dict() + base['pipe_parameters'] = self.pipe_parameters.to_dict() + base['borehole_parameters'] = self.borehole_parameters.to_dict() + base['design_parameters'] = self.design_parameters.to_dict() + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, buildings, location, point=Point2D(0, 0), tolerance=0.01): + """Get GHEThermalLoop dictionary as it appears in an URBANopt geoJSON. + + The resulting dictionary array can be directly appended to the "features" + key of a base GeoJSON dict in order to represent the loop in the + GeoJSON. Note that, in order to successfully simulate the DES, you will also + have to write a system_parameter.json from this GHEThermalLoop using + the to_des_param_dict method. + + Args: + buildings: An array of Dragonfly Building objects that are along + the GHEThermalLoop. Buildings that do not have their footprint + touching the loop's ThermalConnectors are automatically excluded + in the result. + location: A ladybug Location object possessing longitude and latitude data. + point: A ladybug_geometry Point2D for where the location object exists + within the space of a scene. The coordinates of this point are + expected to be in the units of this Model. (Default: (0, 0)). + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # get the conversion factors over to (longitude, latitude) + origin_lon_lat = origin_long_lat_from_location(location, point) + convert_facs = meters_to_long_lat_factors(origin_lon_lat) + + # translate ground heat exchangers into the GeoJSON features list + features_list = [] + for ghe in self.ground_heat_exchangers: + features_list.append(ghe.to_geojson_dict(origin_lon_lat, convert_facs)) + + # get the footprints of the Buildings in 2D space + footprint_2d, bldg_ids = GHEThermalLoop._building_footprints( + buildings, tolerance) + all_feat = \ + footprint_2d + [ghe.boundary_2d for ghe in self.ground_heat_exchangers] + feat_ids = bldg_ids + [ghe.identifier for ghe in self.ground_heat_exchangers] + + # order the connectors correctly on the loop and translate them to features + ordered_conns = self.ordered_connectors(buildings, tolerance) + junctions, connector_jct_ids = self._junctions_from_connectors( + ordered_conns, tolerance) + for conn, jct_ids in zip(self.connectors, connector_jct_ids): + st_feat, end_feat, cp1, cp2 = None, None, conn.geometry.p1, conn.geometry.p2 + for f_poly, f_id in zip(all_feat, feat_ids): + if f_poly.is_point_on_edge(cp1, tolerance): + st_feat = f_id + elif f_poly.is_point_on_edge(cp2, tolerance): + end_feat = f_id + conn_dict = conn.to_geojson_dict( + jct_ids[0], jct_ids[1], origin_lon_lat, convert_facs, st_feat, end_feat) + features_list.append(conn_dict) + + # translate junctions into the GeoJSON features list + for jct in junctions: + for bldg_poly, bldg_id in zip(footprint_2d, bldg_ids): + if bldg_poly.is_point_on_edge(jct.geometry, tolerance): + jct.building_identifier = bldg_id + break + for i, jct in enumerate(junctions): + jct_dict = jct.to_geojson_dict(origin_lon_lat, convert_facs) + if i == 0: + jct_dict['properties']['is_ghe_start_loop'] = True + features_list.append(jct_dict) + return features_list
    + + +
    +[docs] + def to_des_param_dict(self, buildings, tolerance=0.01): + """Get the DES System Parameter dictionary for the ThermalLoop. + + Args: + buildings: An array of Dragonfly Building objects that are along + the GHEThermalLoop. Buildings that do not have their footprint + touching the loop's ThermalConnectors are automatically excluded + in the result. + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # set up a dictionary to be updated with the params + des_dict = {} + + # add the relevant buildings to the DES parameter dictionary + footprint_2d, bldg_ids = GHEThermalLoop._building_footprints( + buildings, tolerance) + rel_bldg_ids = set() + junctions, _ = self.junctions(tolerance) + for jct in junctions: + for bldg_poly, bldg_id in zip(footprint_2d, bldg_ids): + if bldg_poly.is_point_on_edge(jct.geometry, tolerance): + rel_bldg_ids.add(bldg_id) + bldg_array = [] + for bldg_id in rel_bldg_ids: + b_dict = { + 'geojson_id': bldg_id, + 'load_model': 'time_series', + 'load_model_parameters': { + 'time_series': { + 'filepath': 'To be populated', + 'delta_temp_air_cooling': 10, + 'delta_temp_air_heating': 18, + 'has_liquid_cooling': True, + 'has_liquid_heating': True, + 'has_electric_cooling': False, + 'has_electric_heating': False, + 'max_electrical_load': 0, + 'temp_chw_return': 12, + 'temp_chw_supply': 7, + 'temp_hw_return': 35, + 'temp_hw_supply': 40, + 'temp_setpoint_cooling': 24, + 'temp_setpoint_heating': 20 + } + }, + 'ets_model': 'Fifth Gen Heat Pump', + 'fifth_gen_ets_parameters': { + 'supply_water_temperature_building': 15, + 'chilled_water_supply_temp': 5, + 'hot_water_supply_temp': 50, + 'cop_heat_pump_heating': 2.5, + 'cop_heat_pump_cooling': 3.5, + 'pump_flow_rate': 0.01, + 'pump_design_head': 150000, + 'ets_pump_flow_rate': 0.0005, + 'ets_pump_head': 10000, + 'fan_design_flow_rate': 0.25, + 'fan_design_head': 150 + } + } + bldg_array.append(b_dict) + des_dict['buildings'] = bldg_array + + # handle autocalculated soil temperatures + u_temp = self.soil_parameters.undisturbed_temperature \ + if self.soil_parameters._undisturbed_temperature is not None \ + else 'Autocalculate' + + # add the fifth generation system parameters + des_param = { + 'fifth_generation': { + 'ghe_parameters': self.to_ghe_param_dict(tolerance), + 'soil': { + 'conductivity': self.soil_parameters.conductivity, + 'rho_cp': self.soil_parameters.heat_capacity, + 'undisturbed_temp': u_temp + } + } + } + des_dict['district_system'] = des_param + return des_dict
    + + +
    +[docs] + def to_ghe_param_dict(self, tolerance=0.01): + """Get the GroundHeatExchanger as it appears in a System Parameter dictionary. + + Args: + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # compute the geometric constraints of the borehole fields + geo_pars = [] + for ghe in self.ground_heat_exchangers: + ghe_geo = ghe.boundary_2d + max_dim = max((ghe_geo.max.x - ghe_geo.min.x, ghe_geo.max.y - ghe_geo.min.y)) + ang_tol = tolerance / max_dim + if ghe_geo.is_rectangle(ang_tol): + ghe_dims = (ghe_geo.segments[0].length, ghe_geo.segments[1].length) + else: + rect_geo = ghe_geo.rectangular_approximation() + ghe_dims = (rect_geo.segments[0].length, rect_geo.segments[1].length) + geo_par = { + 'ghe_id': ghe.identifier, + 'ghe_geometric_params': { + 'length_of_ghe': max(ghe_dims), + 'width_of_ghe': min(ghe_dims) + }, + 'borehole': { + 'buried_depth': self.borehole_parameters.buried_depth, + 'diameter': self.borehole_parameters.diameter + }, + 'ground_loads': [] + } + geo_pars.append(geo_par) + + # return a dictionary with all of the information + return { + 'fluid': { + 'fluid_name': self.fluid_parameters.fluid_type, + 'concentration_percent': self.fluid_parameters.concentration, + 'temperature': self.fluid_parameters.temperature + }, + 'grout': { + 'conductivity': self.soil_parameters.grout_conductivity, + 'rho_cp': self.soil_parameters.grout_heat_capacity, + }, + 'pipe': { + 'inner_diameter': self.pipe_parameters.inner_diameter, + 'outer_diameter': self.pipe_parameters.outer_diameter, + 'shank_spacing': self.pipe_parameters.shank_spacing, + 'roughness': self.pipe_parameters.roughness, + 'conductivity': self.pipe_parameters.conductivity, + 'rho_cp': self.pipe_parameters.heat_capacity, + 'arrangement': self.pipe_parameters.arrangement.lower() + }, + 'simulation': { + 'num_months': self.design_parameters.month_count + }, + 'geometric_constraints': { + 'b_min': self.borehole_parameters.min_spacing, + 'b_max': self.borehole_parameters.max_spacing, + 'max_height': self.borehole_parameters.max_depth, + 'min_height': self.borehole_parameters.min_depth, + 'method': 'rectangle' + }, + 'design': { + 'method': 'AREAPROPORTIONAL', + 'flow_rate': self.design_parameters.flow_rate, + 'flow_type': self.design_parameters.flow_type.lower(), + 'max_eft': self.design_parameters.max_eft, + 'min_eft': self.design_parameters.min_eft + }, + 'ghe_specific_params': geo_pars + }
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + +
    +[docs] + @staticmethod + def ghe_designer_dict( + thermal_load, site_geometry, soil_parameters=None, fluid_parameters=None, + pipe_parameters=None, borehole_parameters=None, design_parameters=None, + tolerance=0.01): + """Get a dictionary following the schema of the input JSON for GHEDesigner. + + This includes many of the same parameters that are used to size ground + heat exchangers in an URBANopt DES system but it requires the input of + hourly thermal loads. + + The dictionary returned by this method can be written to a JSON and + passed directly to the GHEDesigner CLI in order to receive sizing + information for the GHE and a G-function that can be used to meet + the input load in a building energy simulation. + + Args: + thermal_load: An annual data collection of hourly thermal loads on + the ground in Watts. These are the heat extraction and heat rejection + loads directly on the ground heat exchanger and should already + account for factors like additional heat added or removed by the + heat pump compressors. Positive values indicate heat extraction + from the ground and negative values indicate heat rejection to + the ground. + site_geometry: A list of horizontal Face3D representing the footprint + of the site to be populated with boreholes. These Face3D can + have holes in them and these holes will be excluded from + borehole placement. Note that it is expected that this geometry's + dimensions are in meters and, if they are not, then it should + be scaled before input to this method. + soil_parameters: Optional SoilParameter object to specify the properties + of the soil in which the loop is operating. If None, default + values will be used. (Default: None). + fluid_parameters: Optional FluidParameter object to specify the properties + of the fluid that is circulating through the loop. If None, default + values will be used. (Default: None). + pipe_parameters: Optional PipeParameter object to specify the properties + of the ground-heat-exchanging pipes used across the loop. If None, + default values will be used. (Default: None). + borehole_parameters: Optional BoreholeParameter object to specify the + properties of the boreholes used across the loop. If None, + default values will be used. (Default: None). + design_parameters: Optional GHEDesignParameter object to specify the + design constraints across the loop. If None, default values + will be used. (Default: None). + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # check that the inputs are what we expect + assert isinstance(thermal_load, HourlyContinuousCollection), \ + 'Expected hourly continuous data collection for thermal_load. ' \ + 'Got {}'.format(type(thermal_load)) + period = thermal_load.header.analysis_period + assert period.is_annual and period.timestep == 1, 'Hourly thermal load ' \ + 'is not annual. Analysis period is: {}.'.format(period) + assert thermal_load.header.unit == 'W', 'Expected load data collection to be in Watts. ' \ + 'Got {}.'.format(thermal_load.header.unit) + + # process the input geometry into the format needed for GHEDesigner + site_boundaries, site_holes = [], [] + for face in site_geometry: + bnd_poly = Polygon2D([Point2D(pt.x, pt.y) for pt in face.boundary]) + bnd_poly = bnd_poly.remove_colinear_vertices(tolerance) + if bnd_poly.is_clockwise: + bnd_poly.reverse() + site_boundaries.append([[pt.x, pt.y] for pt in bnd_poly]) + if face.has_holes: + for hole in face.holes: + hole_poly = Polygon2D([Point2D(pt.x, pt.y) for pt in hole]) + hole_poly = hole_poly.remove_colinear_vertices(tolerance) + if hole_poly.is_clockwise: + hole_poly.reverse() + site_holes.append([[pt.x, pt.y] for pt in hole_poly]) + + # set defaults if any of the inputs are unspecified + soil = soil_parameters if soil_parameters is not None else SoilParameter() + fluid = fluid_parameters if fluid_parameters is not None else FluidParameter() + pipe = pipe_parameters if pipe_parameters is not None else PipeParameter() + borehole = borehole_parameters if borehole_parameters is not None \ + else BoreholeParameter() + design = design_parameters if pipe_parameters is not None \ + else GHEDesignParameter() + u_temp = 18.3 if soil._undisturbed_temperature is None \ + else soil.undisturbed_temperature + + # return a dictionary with all of the inputs + return { + 'fluid': { + 'fluid_name': fluid.fluid_type, + 'concentration_percent': fluid.concentration, + 'temperature': fluid.temperature + }, + 'grout': { + 'conductivity': soil.grout_conductivity, + 'rho_cp': soil.grout_heat_capacity + }, + 'soil': { + 'conductivity': soil.conductivity, + 'rho_cp': soil.heat_capacity, + 'undisturbed_temp': u_temp + }, + 'pipe': { + 'inner_diameter': pipe.inner_diameter, + 'outer_diameter': pipe.outer_diameter, + 'shank_spacing': pipe.shank_spacing, + 'roughness': pipe.roughness, + 'conductivity': pipe.conductivity, + 'rho_cp': pipe.heat_capacity, + 'arrangement': pipe.arrangement.upper() + }, + 'borehole': { + 'buried_depth': borehole.buried_depth, + 'diameter': borehole.diameter + }, + 'simulation': { + 'num_months': design.month_count + }, + 'geometric_constraints': { + 'b_min': borehole.min_spacing, + 'b_max_x': borehole.max_spacing, + 'b_max_y': borehole.max_spacing, + 'max_height': borehole.max_depth, + 'min_height': borehole.min_depth, + 'property_boundary': site_boundaries, + 'no_go_boundaries': site_holes, + 'method': 'BIRECTANGLECONSTRAINED' + }, + 'design': { + 'flow_rate': design.flow_rate, + 'flow_type': 'BOREHOLE', + 'max_eft': design.max_eft, + 'min_eft': design.min_eft + }, + 'loads': { + 'ground_loads': thermal_load.values + } + }
    + + +
    +[docs] + @staticmethod + def assign_junction_buildings(junctions, buildings, tolerance=0.01): + """Assign building_identifiers to a list of junctions using dragonfly Buildings. + + Junctions will be assigned to a given Building if they are touching + the footprint of that building in 2D space. + + Args: + junctions: An array of ThermalJunction objects to be associated + with Dragonfly Buildings. + buildings: An array of Dragonfly Building objects in the same units + system as the ThermalLoop geometry. + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # get the footprints of the Buildings in 2D space + footprint_2d, bldg_ids = GHEThermalLoop._building_footprints( + buildings, tolerance) + + # loop through connectors and associate them with the Buildings + for jct in junctions: + for bldg_poly, bldg_id in zip(footprint_2d, bldg_ids): + if bldg_poly.is_point_on_edge(jct.geometry, tolerance): + jct.building_identifier = bldg_id + break + return junctions
    + + + def _junctions_from_connectors(self, connectors, tolerance): + """Get a list of ThermalJunction objects given a list of ThermalConnectors. + """ + # loop through the connectors and find all unique junction objects + junctions, connector_junction_ids = [], [] + for connector in connectors: + verts = connector.geometry.vertices + end_pts, jct_ids = (verts[0], verts[-1]), [] + for jct_pt in end_pts: + for exist_jct in junctions: + if jct_pt.is_equivalent(exist_jct.geometry, tolerance): + jct_ids.append(exist_jct.identifier) + break + else: # we have found a new unique junction + new_jct_id = str(uuid.uuid4()) + junctions.append(ThermalJunction(new_jct_id, jct_pt)) + jct_ids.append(new_jct_id) + connector_junction_ids.append(jct_ids) + + # loop through district system objects to determine adjacent junctions + for jct in junctions: + for ds_obj in self.ground_heat_exchangers: + if ds_obj.boundary_2d.is_point_on_edge(jct.geometry, tolerance): + jct.system_identifier = ds_obj.identifier + break + return junctions, connector_junction_ids + + @staticmethod + def _building_footprints(buildings, tolerance=0.01): + """Get Polygon2Ds for each Dragonfly Building footprint.""" + # get the footprints of the Buildings in 2D space + footprint_2d, bldg_ids = [], [] + for bldg in buildings: + footprint = bldg.footprint(tolerance) + for face3d in footprint: + pts_2d = [Point2D(pt.x, pt.y) for pt in face3d.vertices] + footprint_2d.append(Polygon2D(pts_2d)) + bldg_ids.append(bldg.identifier) + return footprint_2d, bldg_ids + + def __copy__(self): + new_loop = GHEThermalLoop( + self.identifier, + tuple(ghe.duplicate() for ghe in self.ground_heat_exchangers), + tuple(conn.duplicate() for conn in self.connectors), self.clockwise_flow, + self.soil_parameters.duplicate(), self.fluid_parameters.duplicate(), + self.pipe_parameters.duplicate(), self.borehole_parameters.duplicate()) + new_loop._display_name = self._display_name + return new_loop + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'GHEThermalLoop: {}'.format(self.display_name)
    + + + +
    +[docs] +class FourthGenThermalLoop(object): + """Represents a Fourth Generation Heating/Cooling Thermal Loop in a DES. + + Args: + identifier: Text string for a unique thermal loop ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + chilled_water_setpoint: A number for the temperature of chilled water + in the DES in degrees C. (Default: 6). + hot_water_setpoint: A number for the temperature of hot water in the DES + in degrees C. (Default: 54). + + Properties: + * identifier + * display_name + * chilled_water_setpoint + * hot_water_setpoint + """ + __slots__ = ( + '_identifier', '_display_name', '_chilled_water_setpoint', '_hot_water_setpoint') + + def __init__(self, identifier, chilled_water_setpoint=6, hot_water_setpoint=54): + """Initialize GHEThermalLoop.""" + self.identifier = identifier + self._display_name = None + self.chilled_water_setpoint = chilled_water_setpoint + self.hot_water_setpoint = hot_water_setpoint + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize an FourthGenThermalLoop from a dictionary. + + Args: + data: A dictionary representation of an FourthGenThermalLoop object. + """ + # check the type of dictionary + assert data['type'] == 'FourthGenThermalLoop', 'Expected FourthGenThermalLoop ' \ + 'dictionary. Got {}.'.format(data['type']) + cwt = data['chilled_water_setpoint'] if 'chilled_water_setpoint' in data \ + and data['chilled_water_setpoint'] is not None else 6 + hwt = data['hot_water_setpoint'] if 'hot_water_setpoint' in data \ + and data['hot_water_setpoint'] is not None else 54 + loop = cls(data['identifier'], cwt, hwt) + if 'display_name' in data and data['display_name'] is not None: + loop.display_name = data['display_name'] + return loop
    + + + @property + def identifier(self): + """Get or set the text string for unique object identifier.""" + return self._identifier + + @identifier.setter + def identifier(self, identifier): + self._identifier = valid_ep_string(identifier, 'identifier') + + @property + def display_name(self): + """Get or set a string for the object name without any character restrictions. + + If not set, this will be equal to the identifier. + """ + if self._display_name is None: + return self._identifier + return self._display_name + + @display_name.setter + def display_name(self, value): + try: + self._display_name = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._display_name = value # keep it as unicode + + @property + def chilled_water_setpoint(self): + """Get or set a number for the chilled water setpoint in degrees C.""" + return self._chilled_water_setpoint + + @chilled_water_setpoint.setter + def chilled_water_setpoint(self, value): + self._chilled_water_setpoint = \ + float_in_range(value, 0, 20, 'chilled water setpoint') + + @property + def hot_water_setpoint(self): + """Get or set a number for the hot water setpoint in degrees C.""" + return self._hot_water_setpoint + + @hot_water_setpoint.setter + def hot_water_setpoint(self, value): + self._hot_water_setpoint = \ + float_in_range(value, 24, 100, 'hot water setpoint') + +
    +[docs] + def to_dict(self): + """FourthGenThermalLoop dictionary representation.""" + base = {'type': 'FourthGenThermalLoop'} + base['identifier'] = self.identifier + base['chilled_water_setpoint'] = self.chilled_water_setpoint + base['hot_water_setpoint'] = self.hot_water_setpoint + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_des_param_dict(self, buildings, tolerance=0.01): + """Get the DES System Parameter dictionary for the ThermalLoop. + + Args: + buildings: An array of Dragonfly Building objects that are along the + FourthGenThermalLoop. Buildings that do not have their footprint + touching the loop's ThermalConnectors are automatically excluded + in the result. + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # set up a dictionary to be updated with the params + des_dict = {} + # add the relevant buildings to the DES parameter dictionary + bldg_array = [] + for bldg in buildings: + b_dict = { + 'geojson_id': bldg.identifier, + 'load_model': 'time_series', + 'load_model_parameters': { + 'time_series': { + 'filepath': 'To be populated', + 'delta_temp_air_cooling': 10, + 'delta_temp_air_heating': 18, + 'has_liquid_cooling': True, + 'has_liquid_heating': True, + 'has_electric_cooling': False, + 'has_electric_heating': False, + 'max_electrical_load': 0, + 'temp_chw_return': 12, + 'temp_chw_supply': 7, + 'temp_hw_return': 35, + 'temp_hw_supply': 40, + 'temp_setpoint_cooling': 24, + 'temp_setpoint_heating': 20 + } + }, + 'ets_model': 'Indirect Heating and Cooling', + 'ets_indirect_parameters': { + 'heat_flow_nominal': 8000, + 'heat_exchanger_efficiency': 0.8, + 'nominal_mass_flow_district': 0, + 'nominal_mass_flow_building': 0, + 'valve_pressure_drop': 6000, + 'heat_exchanger_secondary_pressure_drop': 500, + 'heat_exchanger_primary_pressure_drop': 500, + 'cooling_supply_water_temperature_building': 7, + 'heating_supply_water_temperature_building': 50, + 'delta_temp_chw_building': 5, + 'delta_temp_chw_district': 8, + 'delta_temp_hw_building': 15, + 'delta_temp_hw_district': 20, + 'cooling_controller_y_max': 1, + 'cooling_controller_y_min': 0, + 'heating_controller_y_max': 1, + 'heating_controller_y_min': 0 + } + } + bldg_array.append(b_dict) + des_dict['buildings'] = bldg_array + + # add the ground loop parameters + des_param = { + 'fourth_generation': { + 'central_cooling_plant_parameters': { + 'heat_flow_nominal': 7999, + 'cooling_tower_fan_power_nominal': 4999, + 'mass_chw_flow_nominal': 9.9, + 'chiller_water_flow_minimum': 9.9, + 'mass_cw_flow_nominal': 9.9, + 'chw_pump_head': 300000, + 'cw_pump_head': 200000, + 'pressure_drop_chw_nominal': 5999, + 'pressure_drop_cw_nominal': 5999, + 'pressure_drop_setpoint': 49999, + 'temp_setpoint_chw': self.chilled_water_setpoint, + 'pressure_drop_chw_valve_nominal': 5999, + 'pressure_drop_cw_pum_nominal': 5999, + 'temp_air_wb_nominal': 24.9, + 'temp_cw_in_nominal': 34.9, + 'cooling_tower_water_temperature_difference_nominal': 6.56, + 'delta_temp_approach': 3.25, + 'ratio_water_air_nominal': 0.6 + }, + 'central_heating_plant_parameters': { + 'heat_flow_nominal': 8001, + 'mass_hhw_flow_nominal': 11, + 'boiler_water_flow_minimum': 11, + 'pressure_drop_hhw_nominal': 55001, + 'pressure_drop_setpoint': 50000, + 'temp_setpoint_hhw': self.hot_water_setpoint, + 'pressure_drop_hhw_valve_nominal': 6001, + 'chp_installed': False + } + } + } + des_dict['district_system'] = des_param + return des_dict
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + new_loop = FourthGenThermalLoop( + self.identifier, self.chilled_water_setpoint, self.hot_water_setpoint) + new_loop._display_name = self._display_name + return new_loop + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'FourthGenThermalLoop: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/measure.html b/docs/_modules/dragonfly_energy/measure.html new file mode 100644 index 00000000..8cc136af --- /dev/null +++ b/docs/_modules/dragonfly_energy/measure.html @@ -0,0 +1,1188 @@ + + + + + + + dragonfly_energy.measure — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.measure

    +# coding=utf-8
    +"""Mange OpenStudio measures that can be mapped to different buildings in a model."""
    +from __future__ import division
    +
    +import os
    +import xml.etree.ElementTree as ElementTree
    +from honeybee_energy.measure import Measure, MeasureArgument
    +
    +
    +
    +[docs] +class MapperMeasure(Measure): + """An OpenStudio measure that can be mapped to different buildings in a model. + + Args: + folder: Path to the folder in which the measure exists. This folder + must contain a measure.rb and a measure.xml file. Other files are + optional. + + Properties: + * folder + * metadata_file + * program_file + * resources_folder + * identifier + * display_name + * description + * type + * arguments + """ + __slots__ = () + + def __init__(self, folder): + """Initialize MapperMeasure.""" + Measure.__init__(self, folder) + +
    +[docs] + @classmethod + def from_dict(cls, data, folder='.'): + """Initialize a MapperMeasure from a dictionary. + + Args: + data: A dictionary in the format below. + folder: Path to a destination folder to save the measure files. (Default '.') + + .. code-block:: python + + { + "type": "MapperMeasure", + "identifier": string, # Measure identifier + "xml_data": string, # XML file data as string + "rb_data": string, # Ruby file data as string + "resource_data": {}, # Dictionary of strings for any resource ruby files + "argument_values": [], # List of values for each of the measure arguments + } + """ + assert data['type'] == 'MapperMeasure', \ + 'Expected MapperMeasure dictionary. Got {}.'.format(data['type']) + fp = os.path.join(folder, data['identifier']) + if not os.path.isdir(fp): + os.makedirs(fp) + + # write out the contents of the measure + xml_fp = os.path.join(fp, 'measure.xml') + cls._decompress_to_file(data['xml_data'], xml_fp) + rb_fp = os.path.join(fp, 'measure.rb') + cls._decompress_to_file(data['rb_data'], rb_fp) + if 'resource_data' in data and data['resource_data'] is not None: + resource_path = os.path.join(fp, 'resources') + os.makedirs(resource_path) + for f_name, res in data['resource_data'].items(): + res_fp = os.path.join(resource_path, f_name) + cls._decompress_to_file(res, res_fp) + + # create the measure object and assign the arguments + new_measure = cls(fp) + for arg, val in zip(new_measure.arguments, data['argument_values']): + if val is not None: + arg.value = val + return new_measure
    + + +
    +[docs] + def to_dict(self): + """Convert MapperMeasure to a dictionary.""" + base = Measure.to_dict(self) + base['type'] = 'MapperMeasure' + return base
    + + +
    +[docs] + def to_osw_dict(self, full_path=False): + """Get a Python dictionary that can be written to an OSW JSON. + + Specifically, this dictionary can be appended to the "steps" key of the + OpenStudio Workflow (.osw) JSON dictionary in order to include the measure + in the workflow. + + Note that this method does not perform any checks to validate that the + Measure has all required values and only arguments with values will be + included in the dictionary. Validation should be done separately with + the validate method. + + Args: + full_path: Boolean to note whether the full path to the measure should + be written under the 'measure_dir_name' key or just the measure + base name. (Default: False) + """ + meas_dir = self.folder if full_path else os.path.basename(self.folder) + base = {'measure_dir_name': meas_dir, 'arguments': {}} + for arg in self._arguments: + if arg.value is not None: + base['arguments'][arg.identifier] = arg.value \ + if not isinstance(arg.value, tuple) else arg.value[0] + return base
    + + + def _parse_metadata_file(self): + """Parse measure properties from the measure.xml file.""" + # create an element tree object + tree = ElementTree.parse(self._metadata_file) + root = tree.getroot() + + # parse the measure properties from the element tree + self._identifier = root.find('name').text + self._display_name = root.find('display_name').text + self._description = root.find('description').text + self._type = None + for atr in root.find('attributes'): + if atr.find('name').text == 'Measure Type': + self._type = atr.find('value').text + + # parse the measure arguments + self._arguments = [] + for arg in root.find('arguments'): + arg_obj = MapperMeasureArgument(arg) + if arg_obj.model_dependent: + # TODO: Figure out how to implement model-dependent arguments + raise NotImplementedError( + 'Model dependent arguments are not yet supported and measure ' + 'argument is "{}" model dependent.'.format(arg_obj.identifier)) + self._arguments.append(arg_obj) + + def __repr__(self): + return 'MapperMeasure: {}'.format(self.display_name)
    + + + +
    +[docs] +class MapperMeasureArgument(MeasureArgument): + """Object representing a single mapper measure argument. + + Args: + xml_element: A Python XML Element object taken from the <arguments> section + of the measure.xml file. + + Properties: + * identifier + * display_name + * value + * default_value + * type + * type_text + * required + * description + * model_dependent + * valid_choices + """ + __slots__ = () + + def __init__(self, xml_element): + """Initialize MeasureArgument.""" + MeasureArgument.__init__(self, xml_element) + + @property + def value(self): + """Get or set the value or list of values for the argument. + + When using a list, the length of it must match the number of buildings in + the dragonfly Model and each value corresponds to a building under the + Model.buildings property. + + If not set, this will be equal to the default_value and, if no default + value is included for this argument, it will be None. + """ + if self._value is not None: + return self._value + return self._default_value + + @value.setter + def value(self, val): + if val is not None: + e_msg = 'Value for measure argument "' + self.identifier + \ + '" must be a {}. Got {}' + if not isinstance(val, (list, tuple)): + val = (val,) + try: + val = tuple(self._type(v) for v in val) + except Exception: + raise TypeError(e_msg.format(self._type, type(val))) + if self._valid_choices: + assert all(v in self._valid_choices for v in val), \ + 'Choice measure argument "{}" ' \ + 'must be one of the following:\n{}\nGot {}'.format( + self.identifier, self._valid_choices, val) + self._value = val if val is None or len(val) != 1 else val[0]
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/colorobj.html b/docs/_modules/dragonfly_energy/opendss/colorobj.html new file mode 100644 index 00000000..eb59369b --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/colorobj.html @@ -0,0 +1,1310 @@ + + + + + + + dragonfly_energy.opendss.colorobj — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.colorobj

    +"""Module for coloring OpenDSS geometry with attributes."""
    +from ladybug_geometry.geometry2d import Point2D
    +from ladybug_geometry.geometry3d import Point3D
    +from ladybug.datacollection import HourlyContinuousCollection, \
    +    HourlyDiscontinuousCollection
    +from ladybug.graphic import GraphicContainer
    +from ladybug.legend import LegendParameters
    +from honeybee.typing import int_in_range
    +from honeybee.colorobj import _ColorObject
    +
    +from .network import ElectricalNetwork
    +
    +
    +
    +[docs] +class ColorNetwork(_ColorObject): + """Object for visualizing ElectricalNetwork attributes. + + Args: + network: An ElectricalNetwork object, which will be colored with the attribute. + attr_name: A text string of an attribute that the input network equipment has. + This can have '.' that separate the nested attributes from one another. + For example, 'properties.kva' for the kva rating of transformers. + legend_parameters: An optional LegendParameter object to change the display + of the results (Default: None). + + Properties: + * network + * attr_name + * legend_parameters + * attr_name_end + * attributes + * attributes_unique + * attributes_original + * geometries + * graphic_container + * min_point + * max_point + """ + __slots__ = ('_network', '_geometries') + + def __init__(self, network, attr_name, legend_parameters=None): + """Initialize ColorNetwork.""" + assert isinstance(network, ElectricalNetwork), 'Expected ElectricalNetwork for' \ + ' ColorNetwork. Got {}.'.format(type(network)) + self._network = network + all_obj = (network.substation,) + network.transformers + network.connectors + self._geometries = tuple(obj.geometry for obj in all_obj) + self._min_point, self._max_point = _calculate_min_max(all_obj) + + # assign the legend parameters of this object + self.legend_parameters = legend_parameters + + # get the attributes of the input equipment + self._process_attribute_name(attr_name) + self._process_attributes(all_obj) + + @property + def network(self): + """Get the ElectricalNetwork associated with this object.""" + return self._network + + @property + def geometries(self): + """A tuple of Polygon2D, Polyline2D and LineSegment2D aligned with attributes. + """ + return self._geometries + + @property + def min_point(self): + """Get a Point3D for the minimum of the box around the objects.""" + return Point3D(self._min_point.x, self._min_point.y, 0) + + @property + def max_point(self): + """Get a Point3D for the maximum of the box around the objects.""" + return Point3D(self._max_point.x, self._max_point.y, 0) + + def __repr__(self): + """Color ElectricalNetwork representation.""" + return 'Color Network: {} [{}]'.format( + self.network.display_name, self.attr_name_end)
    + + + +
    +[docs] +class ColorNetworkResults(object): + """Class for coloring ElectricalNetwork geometry with simulation results. + + Args: + data_collections: An array of data collections of the same data type, + which will be used to color the network with simulation results. Data + collections should all have headers with metadata dictionaries with 'type' + and 'name' keys. These keys will be used to match the data in the collections + to the input electrical network. + network: An ElectricalNetwork object, which will be colored with the attribute. + legend_parameters: An optional LegendParameter object to change the display + of the ColorNetworkResults (Default: None). + attribute: Text to note the attribute of the data collections with which the + network geometry should be colored. Typical values are max, min, average, + median, or total. This input can also be an integer (greater than or equal + to 0) to select a specific step of the data collections for which result + values will be generated. (Default: "Max" to color with the peak value). + + Properties: + * data_collections + * network + * legend_parameters + * attribute + * matched_geometries + * matched_data + * matched_values + * graphic_container + * title_text + * data_type_text + * data_type + * unit + * analysis_period + * min_point + * max_point + """ + __slots__ = ( + '_data_collections', '_network', '_legend_parameters', '_attribute', + '_matched_geometries', '_matched_data', '_matched_values', + '_base_collection', '_base_type', '_base_unit', '_min_point', '_max_point') + + def __init__(self, data_collections, network, + legend_parameters=None, attribute='max'): + """Initialize ColorNetworkResults.""" + # check the input collections + accept_cols = (HourlyContinuousCollection, HourlyDiscontinuousCollection) + try: + data_collections = list(data_collections) + except TypeError: + raise TypeError('Input data_collections must be an array. Got {}.'.format( + type(data_collections))) + assert len(data_collections) > 0, \ + 'ColorNetworkResults must have at least one data_collection.' + for i, coll in enumerate(data_collections): + assert isinstance(coll, accept_cols), 'Expected hourly ' \ + 'data collection for ColorNetworkResults. Got {}.'.format(type(coll)) + self._base_collection = data_collections[0] + self._base_type = self._base_collection.header.data_type + self._base_unit = self._base_collection.header.unit + for coll in data_collections[1:]: + assert coll.header.unit == self._base_unit, \ + 'ColorNetworkResults data_collections must all have matching units. ' \ + '{} != {}.'.format(coll.header.unit, self._base_unit) + assert len(coll.values) == len(self._base_collection.values), \ + 'ColorNetworkResults data_collections must be aligned with one another' \ + '.{} != {}'.format(len(coll.values), len(self._base_collection.values)) + self._data_collections = data_collections + + # process the input electrical network + assert isinstance(network, ElectricalNetwork), 'Expected ElectricalNetwork for' \ + ' ColorNetworkResults. Got {}.'.format(type(network)) + self._network = network + all_obj = (network.substation,) + network.transformers + network.connectors + self._min_point, self._max_point = _calculate_min_max(all_obj) + geo_dict = {obj.identifier.lower().replace(':', ''): obj.geometry + for obj in all_obj} + self._matched_geometries, self._matched_data = [], [] + for dat in self._data_collections: + try: + self._matched_geometries.append( + geo_dict[dat.header.metadata['name'].replace(':', '')]) + self._matched_data.append(dat) + except KeyError: # data could not be matched + pass + + # assign the other properties of this object + self.legend_parameters = legend_parameters + self.attribute = attribute + + @property + def data_collections(self): + """Get a tuple of data collections assigned to this object.""" + return tuple(self._data_collections) + + @property + def network(self): + """Get the ElectricalNetwork associated with this object.""" + return self._network + + @property + def geometries(self): + """A tuple of Polygon2D, Polyline2D and LineSegment2D aligned with attributes. + """ + return self._geometries + + @property + def legend_parameters(self): + """Get or set the legend parameters.""" + return self._legend_parameters + + @legend_parameters.setter + def legend_parameters(self, value): + if value is not None: + assert isinstance(value, LegendParameters), \ + 'Expected LegendParameters. Got {}.'.format(type(value)) + self._legend_parameters = value.duplicate() + else: + self._legend_parameters = LegendParameters() + + @property + def attribute(self): + """Get or set text for the data attribute or an integer a specific data step.""" + return self._attribute + + @attribute.setter + def attribute(self, value): + if not hasattr(self._base_collection, value): + value = int_in_range( + value, 0, len(self._base_collection) - 1, 'simulation step') + self._attribute = value + + @property + def matched_geometries(self): + """Get a tuple of geometries that were matched with the data collections.""" + return tuple(self._matched_geometries) + + @property + def matched_data(self): + """Get a tuple of data collections aligned with the matched_geometries.""" + return tuple(self._matched_data) + + @property + def matched_values(self): + """Get an array of numbers that correspond to the matched_geometries. + + These values are derived from the data_collections but they will be + averaged/totaled or for a specific time step depending on the + other inputs to this object. + """ + if isinstance(self.attribute, int): # specific index from all collections + return tuple(data[self._attribute] for data in self._matched_data) + else: # data collection property + return tuple(getattr(data, self._attribute) + for data in self._matched_data) + + @property + def graphic_container(self): + """Get a ladybug GraphicContainer that relates to this object. + + The GraphicContainer possesses almost all things needed to visualize the + object including the legend, value_colors, lower_title_location, + upper_title_location, etc. + """ + return GraphicContainer( + self.matched_values, self.min_point, self.max_point, + self.legend_parameters, self.data_type, str(self.unit)) + + @property + def title_text(self): + """Text string for the title of the object.""" + d_type_text = self.data_type + if isinstance(self.attribute, int): # specific index from all collections + time_text = self.time_interval_text(self.attribute) + else: # average or total the data + time_text = str(self.analysis_period).split('@')[0] + d_type_text = '{} {}'.format(self.attribute.capitalize(), d_type_text) + return '{}\n{}'.format('{} ({})'.format(d_type_text, self.unit), time_text) + + @property + def data_type(self): + """Text for the data type.""" + return self._base_type + + @property + def unit(self): + """The unit of this object's data collections.""" + return self._base_unit + + @property + def analysis_period(self): + """The analysis_period of this object's data collections.""" + return self._base_collection.header.analysis_period + + @property + def min_point(self): + """Get a Point3D for the minimum of the box around the objects.""" + return Point3D(self._min_point.x, self._min_point.y, 0) + + @property + def max_point(self): + """Get a Point3D for the maximum of the box around the objects.""" + return Point3D(self._max_point.x, self._max_point.y, 0) + +
    +[docs] + def time_interval_text(self, simulation_step): + """Get text for a specific time simulation_step of the data collections. + + Args: + simulation_step: An integer for the step of simulation for which + text should be generated. + """ + return str(self._base_collection.datetimes[simulation_step])
    + + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString.""" + return self.__repr__()
    + + + def __repr__(self): + """Color Network representation.""" + return 'Color Network results: {} [{} results]'.format( + self.network.display_name, len(self._data_collections))
    + + + +def _calculate_min_max(net_objs): + """Calculate maximum and minimum Point3D for a set of objects.""" + st_rm_min, st_rm_max = net_objs[0].geometry.min, net_objs[0].geometry.max + min_pt = [st_rm_min.x, st_rm_min.y] + max_pt = [st_rm_max.x, st_rm_max.y] + + for obj in net_objs[1:]: + rm_min, rm_max = obj.geometry.min, obj.geometry.max + if rm_min.x < min_pt[0]: + min_pt[0] = rm_min.x + if rm_min.y < min_pt[1]: + min_pt[1] = rm_min.y + if rm_max.x > max_pt[0]: + max_pt[0] = rm_max.x + if rm_max.y > max_pt[1]: + max_pt[1] = rm_max.y + + return Point2D(min_pt[0], min_pt[1]), Point2D(max_pt[0], max_pt[1]) +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/connector.html b/docs/_modules/dragonfly_energy/opendss/connector.html new file mode 100644 index 00000000..a42e77fb --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/connector.html @@ -0,0 +1,1194 @@ + + + + + + + dragonfly_energy.opendss.connector — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.connector

    +# coding=utf-8
    +"""Electrical connector in OpenDSS."""
    +from __future__ import division
    +
    +from .._base import _GeometryBase
    +from .powerline import PowerLine
    +
    +from ladybug_geometry.geometry2d.line import LineSegment2D
    +from ladybug_geometry.geometry2d.polyline import Polyline2D
    +from dragonfly.projection import polygon_to_lon_lat
    +
    +
    +
    +[docs] +class ElectricalConnector(_GeometryBase): + """Represents an electrical connector carrying wires in OpenDSS. + + Args: + identifier: Text string for a unique electrical connector ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + geometry: A LineSegment2D or Polyline2D representing the geometry of the + electrical connector. + power_line: A PowerLine object representing the wires carried along the + electrical connector and their arrangement. + + Properties: + * identifier + * display_name + * geometry + * power_line + * phase_count + * nominal_voltage + """ + __slots__ = ('_power_line',) + + def __init__(self, identifier, geometry, power_line): + """Initialize ElectricalConnector.""" + _GeometryBase.__init__(self, identifier) # process the identifier + assert isinstance(geometry, (LineSegment2D, Polyline2D)), 'Expected ' \ + 'ladybug_geometry LineSegment2D or Polyline2D. Got {}'.format(type(geometry)) + self._geometry = geometry + self.power_line = power_line + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize an ElectricalConnector from a dictionary. + + Args: + data: A dictionary representation of an ElectricalConnector object. + """ + # check the type of dictionary + assert data['type'] == 'ElectricalConnector', 'Expected ElectricalConnector ' \ + 'dictionary. Got {}.'.format(data['type']) + power_line = PowerLine.from_dict(data['power_line']) + geo = LineSegment2D.from_dict(data['geometry']) \ + if data['geometry']['type'] == 'LineSegment2D' \ + else Polyline2D.from_dict(data['geometry']) + con = cls(data['identifier'], geo, power_line) + if 'display_name' in data and data['display_name'] is not None: + con.display_name = data['display_name'] + return con
    + + +
    +[docs] + @classmethod + def from_dict_abridged(cls, data, power_lines): + """Initialize an ElectricalConnector from an abridged dictionary. + + Args: + data: A ElectricalConnectorAbridged dictionary. + power_lines: A dictionary with identifiers of PowerLines as keys and Python + PowerLine objects as values. + """ + assert data['type'] == 'ElectricalConnectorAbridged', \ + 'Expected ElectricalConnectorAbridged. Got {}.'.format(data['type']) + try: + power_line = power_lines[data['power_line']] + except KeyError as e: + raise ValueError('Failed to find "{}" in power lines.'.format(e)) + geo = LineSegment2D.from_dict(data['geometry']) \ + if data['geometry']['type'] == 'LineSegment2D' \ + else Polyline2D.from_dict(data['geometry']) + con = cls(data['identifier'], geo, power_line) + if 'display_name' in data and data['display_name'] is not None: + con.display_name = data['display_name'] + return con
    + + +
    +[docs] + @classmethod + def from_rnm_geojson_dict( + cls, data, origin_lon_lat, conversion_factors, power_lines): + """Get an ElectricalConnector from a dictionary as it appears in an RNM GeoJSON. + + Args: + data: A GeoJSON dictionary representation of an ElectricalConnector feature. + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + power_lines: A dictionary with identifiers of PowerLines as keys and Python + PowerLine objects as values. + """ + geo = cls._geojson_coordinates_to_line2d( + data['geometry']['coordinates'], origin_lon_lat, conversion_factors) + try: + power_line = power_lines[data['properties']['Equip']] + except KeyError as e: + raise ValueError('Failed to find "{}" in power lines.'.format(e)) + return cls(data['properties']['Code'], geo, power_line)
    + + + @property + def geometry(self): + """Get a LineSegment2D or Polyline2D representing the electrical connector.""" + return self._geometry + + @property + def power_line(self): + """Get or set the PowerLine object carried along the electrical connector.""" + return self._power_line + + @power_line.setter + def power_line(self, value): + assert isinstance(value, PowerLine), 'Expected PowerLine object' \ + ' for electrical connector power_line. Got {}.'.format(type(value)) + value.lock() # lock to avoid editing + self._power_line = value + + @property + def phase_count(self): + """Get an integer for the number of phases this connector supports.""" + return self._power_line.phase_count + + @property + def nominal_voltage(self): + """Get an integer for the nominal voltage of this connector.""" + return self._power_line.nominal_voltage + +
    +[docs] + def to_dict(self, abridged=False): + """ElectricalConnector dictionary representation. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True), + which only specifies the identifier of the power line. (Default: False). + """ + base = {'type': 'ElectricalConnector'} if not \ + abridged else {'type': 'ElectricalConnectorAbridged'} + base['identifier'] = self.identifier + base['geometry'] = self.geometry.to_dict() + base['power_line'] = self.power_line.identifier if abridged \ + else self.power_line.to_dict() + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, start_id, end_id, origin_lon_lat, conversion_factors): + """Get ElectricalConnector dictionary as it appears in an URBANopt geoJSON. + + Args: + start_id: Identifier of the junction at the start of the wire. + end_id: Identifier of the junction at the end of the wire. + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + if isinstance(self.geometry, LineSegment2D): + pts = [(pt.x, pt.y) for pt in (self.geometry.p1, self.geometry.p2)] + else: # it's a polyline + pts = [(pt.x, pt.y) for pt in self.geometry.vertices] + coords = polygon_to_lon_lat(pts, origin_lon_lat, conversion_factors) + return { + 'type': 'Feature', + 'properties': { + 'id': self.identifier, + 'type': 'ElectricalConnector', + 'startJunctionId': start_id, + 'endJunctionId': end_id, + 'total_length': round(self.geometry.length, 2), + 'connector_type': 'Wire', + 'electrical_catalog_name': self.power_line.identifier, + 'name': self.display_name + }, + 'geometry': { + 'type': 'LineString', + 'coordinates': coords + } + }
    + + + def __copy__(self): + new_con = ElectricalConnector(self.identifier, self.geometry, self.power_line) + new_con._display_name = self._display_name + return new_con + + def __repr__(self): + return 'ElectricalConnector: {}, [{} wires]'.format( + self.display_name, self.power_line.wire_count)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/junction.html b/docs/_modules/dragonfly_energy/opendss/junction.html new file mode 100644 index 00000000..dfeba697 --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/junction.html @@ -0,0 +1,1093 @@ + + + + + + + dragonfly_energy.opendss.junction — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.junction

    +# coding=utf-8
    +"""Electrical junction in OpenDSS."""
    +from __future__ import division
    +
    +from .._base import _GeometryBase
    +
    +from ladybug_geometry.geometry2d.pointvector import Point2D
    +from honeybee.typing import valid_ep_string
    +from dragonfly.projection import polygon_to_lon_lat
    +
    +
    +
    +[docs] +class ElectricalJunction(_GeometryBase): + """Represents an electrical junction connecting two or more objects in OpenDSS. + + Args: + identifier: Text string for a unique electrical junction ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + geometry: A LineSegment2D or Polyline2D representing the geometry of the + electrical junction. + system_identifier: An optional text string for the identifier of a district + system object associated with the junction. District system objects + include Transformers and Substations. (Default: None). + building_identifier: An optional text string for the identifier of a Building + object associated with the junction. (Default: None). + + Properties: + * identifier + * display_name + * geometry + * system_identifier + * building_identifier + """ + __slots__ = ('_system_identifier', '_building_identifier') + + def __init__(self, identifier, geometry, system_identifier=None, + building_identifier=None): + """Initialize ElectricalJunction.""" + _GeometryBase.__init__(self, identifier) # process the identifier + assert isinstance(geometry, Point2D), 'Expected ladybug_geometry ' \ + 'Point2D for ElectricalJunction. Got {}'.format(type(geometry)) + self._geometry = geometry + self.system_identifier = system_identifier + self.building_identifier = building_identifier + + @property + def geometry(self): + """Get a Point2D representing the ElectricalJunction.""" + return self._geometry + + @property + def system_identifier(self): + """Get or set a text string for the ID of a Transformer or Substation.""" + return self._system_identifier + + @system_identifier.setter + def system_identifier(self, value): + self._system_identifier = valid_ep_string(value, 'system_identifier') \ + if value is not None else None + + @property + def building_identifier(self): + """Get or set a text string for the ID of a dragonfly Building.""" + return self._building_identifier + + @building_identifier.setter + def building_identifier(self, value): + self._building_identifier = valid_ep_string(value, 'building_identifier') \ + if value is not None else None + +
    +[docs] + def to_geojson_dict(self, origin_lon_lat, conversion_factors): + """Get an ElectricalJunction dictionary as it appears in an URBANopt geoJSON. + + Args: + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + pt = (self.geometry.x, self.geometry.y) + coord = polygon_to_lon_lat([pt], origin_lon_lat, conversion_factors)[0] + geo_dict = { + 'type': 'Feature', + 'properties': { + 'id': self.identifier, + 'type': 'ElectricalJunction' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': coord + } + } + if self._system_identifier is not None: + geo_dict['properties']['DSId'] = self._system_identifier + if self._building_identifier is not None: + geo_dict['properties']['buildingId'] = self._building_identifier + return geo_dict
    + + + def __copy__(self): + new_jct = ElectricalJunction( + self.identifier, self.geometry, self._system_identifier, + self._building_identifier) + new_jct._display_name = self._display_name + return new_jct + + def __repr__(self): + return 'ElectricalJunction: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/lib/powerlines.html b/docs/_modules/dragonfly_energy/opendss/lib/powerlines.html new file mode 100644 index 00000000..6d05ebaa --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/lib/powerlines.html @@ -0,0 +1,1015 @@ + + + + + + + dragonfly_energy.opendss.lib.powerlines — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.lib.powerlines

    +"""Library of power lines that come standard with dragonfly."""
    +import os
    +import json
    +
    +from ..powerline import PowerLine
    +from .wires import _wires
    +
    +
    +# load the  defaults
    +_power_lines = {}
    +_data_path = os.path.join(os.path.dirname(__file__), 'extended_catalog.json')
    +with open(_data_path) as json_file:
    +    _all_data = json.load(json_file)['LINES']
    +    _default_data = _all_data[1]['#Interurban Zone A:'] + \
    +        _all_data[2]['#Urban-Overhead'] + _all_data[3]['#Urban-Underground']
    +for _t_dict in _default_data:
    +    _t_obj = PowerLine.from_electrical_database_dict(_t_dict, _wires)
    +    _t_obj.lock()
    +    _power_lines[_t_dict['Name']] = _t_obj
    +
    +POWER_LINES = tuple(_power_lines.keys())
    +
    +
    +
    +[docs] +def power_line_by_identifier(power_line_identifier): + """Get power line properties from the library given the identifier. + + Args: + power_line_identifier: A text string for the identifier of the power line. + """ + try: + return _power_lines[power_line_identifier] + except KeyError: + raise ValueError( + '"{}" was not found in the power line library.'.format( + power_line_identifier))
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/lib/transformers.html b/docs/_modules/dragonfly_energy/opendss/lib/transformers.html new file mode 100644 index 00000000..2874f3ee --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/lib/transformers.html @@ -0,0 +1,1016 @@ + + + + + + + dragonfly_energy.opendss.lib.transformers — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.lib.transformers

    +"""Library of transformer properties that come standard with dragonfly."""
    +from ..transformerprop import TransformerProperties
    +
    +import os
    +import json
    +
    +# load the  defaults
    +_transformers = {}
    +_data_path = os.path.join(os.path.dirname(__file__), 'extended_catalog.json')
    +with open(_data_path) as json_file:
    +    _all_data = json.load(json_file)['SUBSTATIONS AND DISTRIBUTION TRANSFORMERS']
    +    for dat in reversed(_all_data):  # the last interurban one has transformers
    +        if '#Interurban:' in dat:
    +            _default_data = dat['#Interurban:']
    +            break
    +for _t_dict in _default_data:
    +    _t_obj = TransformerProperties.from_electrical_database_dict(_t_dict)
    +    _t_obj.lock()
    +    _transformers[_t_dict['Name']] = _t_obj
    +
    +TRANSFORMER_PROPERTIES = tuple(_transformers.keys())
    +
    +
    +
    +[docs] +def transformer_prop_by_identifier(transformer_identifier): + """Get transformer properties from the library given the identifier. + + Args: + transformer_identifier: A text string for the identifier of the transformer + properties. + """ + try: + return _transformers[transformer_identifier] + except KeyError: + raise ValueError( + '"{}" was not found in the transformer property library.'.format( + transformer_identifier))
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/lib/wires.html b/docs/_modules/dragonfly_energy/opendss/lib/wires.html new file mode 100644 index 00000000..b013db6d --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/lib/wires.html @@ -0,0 +1,1010 @@ + + + + + + + dragonfly_energy.opendss.lib.wires — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.lib.wires

    +"""Library of wires that come standard with dragonfly."""
    +import os
    +import json
    +from ..wire import Wire
    +
    +
    +# load the  defaults
    +_wires = {}
    +_data_path = os.path.join(os.path.dirname(__file__), 'extended_catalog.json')
    +with open(_data_path) as json_file:
    +    _default_data = json.load(json_file)['WIRES']['WIRES CATALOG']
    +for _t_dict in _default_data:
    +    _t_obj = Wire.from_electrical_database_dict(_t_dict)
    +    _t_obj.lock()
    +    _wires[_t_dict['nameclass']] = _t_obj
    +
    +WIRES = tuple(_wires.keys())
    +
    +
    +
    +[docs] +def wire_by_identifier(wire_identifier): + """Get wire properties from the library given the identifier. + + Args: + wire_identifier: A text string for the identifier of the wire. + """ + try: + return _wires[wire_identifier] + except KeyError: + raise ValueError( + '"{}" was not found in the wire library.'.format(wire_identifier))
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/network.html b/docs/_modules/dragonfly_energy/opendss/network.html new file mode 100644 index 00000000..efc52eb8 --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/network.html @@ -0,0 +1,1828 @@ + + + + + + + dragonfly_energy.opendss.network — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.network

    +# coding=utf-8
    +"""Electrical network in OpenDSS."""
    +import os
    +import uuid
    +import json
    +
    +from ladybug_geometry.geometry2d import Point2D, Polygon2D
    +from ladybug.location import Location
    +from honeybee.typing import valid_ep_string
    +from honeybee.units import conversion_factor_to_meters
    +from dragonfly.projection import meters_to_long_lat_factors, \
    +    origin_long_lat_from_location
    +
    +from .substation import Substation
    +from .transformer import Transformer
    +from .connector import ElectricalConnector
    +from .junction import ElectricalJunction
    +from .road import Road
    +from .transformerprop import TransformerProperties
    +from .powerline import PowerLine
    +from .wire import Wire
    +from .lib.powerlines import power_line_by_identifier
    +
    +
    +
    +[docs] +class ElectricalNetwork(object): + """Represents an electrical network in OpenDSS. + + This includes a substation, transformers, and all electrical connectors needed + to connect these objects to Dragonfly Buildings. + + Args: + identifier: Text string for a unique electrical network ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + substation: A Substation object representing the electrical substation + supplying the network with electricity. + transformers: An array of Transformer objects that are included within the + electrical network. Generally, there should always be a transformer + somewhere between the substation and a given building. + connectors: An array of ElectricalConnector objects that are included + within the electrical network. In order for a given connector to be + valid within the network, each end of the connector must touch either + another connector or a building footprint/transformer/substation. In + order for the network as a whole to be valid, all Buildings and + Transformers must be connected back to the Substation via connectors. + + Properties: + * identifier + * display_name + * substation + * transformers + * connectors + * transformer_properties + * power_lines + * wires + """ + __slots__ = ('_identifier', '_display_name', '_substation', + '_transformers', '_connectors') + + def __init__(self, identifier, substation, transformers, connectors): + """Initialize ElectricalNetwork.""" + self.identifier = identifier + self._display_name = None + self.substation = substation + self.transformers = transformers + self.connectors = connectors + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize an ElectricalNetwork from a dictionary. + + Args: + data: A dictionary representation of an ElectricalNetwork object. + """ + # check the type of dictionary + assert data['type'] == 'ElectricalNetwork', 'Expected ElectricalNetwork ' \ + 'dictionary. Got {}.'.format(data['type']) + # re-serialize transformer properties and wires + t_props = {tp['identifier']: TransformerProperties.from_dict(tp) + for tp in data['transformer_properties']} + wires = {w['identifier']: Wire.from_dict(w) for w in data['wires']} + power_lines = {pl['identifier']: PowerLine.from_dict_abridged(pl, wires) + for pl in data['power_lines']} + # re-serialize geometry objects + substation = Substation.from_dict(data['substation']) + transformers = [Transformer.from_dict_abridged(trans, t_props) + for trans in data['transformers']] + conns = [ElectricalConnector.from_dict_abridged(c, power_lines) + for c in data['connectors']] + net = cls(data['identifier'], substation, transformers, conns) + if 'display_name' in data and data['display_name'] is not None: + net.display_name = data['display_name'] + return net
    + + +
    +[docs] + @classmethod + def from_rnm_geojson( + cls, geojson_file_path, location=None, point=None, units='Meters'): + """Get an ElectricalNetwork from a dictionary as it appears in an RNM GeoJSON. + + Args: + geojson_file_path: Text for the full path to the geojson file to load + as a ElectricalNetwork. + location: An optional ladybug location object with longitude and + latitude data defining the origin of the geojson file. If None, + an attempt will be made to sense the location from the project + point in the GeoJSON (if it exists). If nothing is found, the + origin is autocalcualted as the bottom-left corner of the bounding + box of all building footprints in the geojson file. (Default: None). + point: A ladybug_geometry Point2D for where the location object exists + within the space of a scene. The coordinates of this point are + expected to be in the units input. If None, an attempt will be + made to sense the CAD coordinates from the GeoJSON if they + exist. If not found, they will default to (0, 0). + units: Text for the units system in which the model geometry + exists. Default: 'Meters'. Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + Note that this method assumes the point coordinates are in the + same units. + """ + # parse the geoJSON into a dictionary + with open(geojson_file_path, 'r') as fp: + data = json.load(fp) + + # extract the CAD coordinates and location from the GeoJSON if they exist + if 'project' in data: + prd = data['project'] + if 'latitude' in prd and 'longitude' in prd and location is None: + location = Location(latitude=prd['latitude'], longitude=prd['longitude']) + if 'cad_coordinates' in prd and point is None: + point = Point2D(*prd['cad_coordinates']) + if point is None: # just use the world origin if no point was found + point = Point2D(0, 0) + + # Get the list of substation, transformer and electrical connector data + transf_data, connector_data, subst_data = [], [], None + for obj_data in data['features']: + if 'type' in obj_data['properties']: + if obj_data['properties']['type'] == 'Line': + connector_data.append(obj_data) + elif obj_data['properties']['type'] == 'DistribTransf': + transf_data.append(obj_data) + elif 'Substation' in obj_data['properties']['type']: + subst_data = obj_data + + # if model units is not Meters, convert non-meter user inputs to meters + scale_to_meters = conversion_factor_to_meters(units) + if units != 'Meters': + point = point.scale(scale_to_meters) + + # Get long and lat in the geojson that correspond to the model origin (point). + # If location is None, derive coordinates from the geojson geometry. + if location is None: + point_lon_lat = cls._bottom_left_coordinate_from_geojson(connector_data) + location = Location(longitude=point_lon_lat[0], latitude=point_lon_lat[1]) + + # The model point may not be at (0, 0), so shift the longitude and latitude to + # get the equivalent point in longitude and latitude for (0, 0) in the model. + origin_lon_lat = origin_long_lat_from_location(location, point) + _convert_facs = meters_to_long_lat_factors(origin_lon_lat) + convert_facs = 1 / _convert_facs[0], 1 / _convert_facs[1] + + # extract the connectors + power_line_dict = { + p['properties']['Equip']: power_line_by_identifier(p['properties']['Equip']) + for p in connector_data + } + connectors = [] + for con_data in connector_data: + con_obj = ElectricalConnector.from_rnm_geojson_dict( + con_data, origin_lon_lat, convert_facs, power_line_dict) + connectors.append(con_obj) + # extract the transformers + transformers = [] + for trn_data in transf_data: + trn_obj = Transformer.from_rnm_geojson_dict( + trn_data, origin_lon_lat, convert_facs) + transformers.append(trn_obj) + # extract the substation + substation = Substation.from_rnm_geojson_dict( + subst_data, origin_lon_lat, convert_facs) + + # create the network and adjust for the units + base_name = os.path.basename(geojson_file_path) + net_id = base_name.replace('.json', '').replace('.geojson', '') + net = cls(net_id, substation, transformers, connectors) + if units != 'Meters': + net.convert_to_units(units) + return net
    + + + @staticmethod + def _bottom_left_coordinate_from_geojson(connector_data): + """Calculate the bottom-left bounding box coordinate from geojson coordinates. + + Args: + connector_data: a list of dictionaries containing geojson geometries that + represent electrical connectors. + + Returns: + The bottom-left most corner of the bounding box around the coordinates. + """ + xs, ys = [], [] + for conn in connector_data: + conn_coords = conn['geometry']['coordinates'] + if conn['geometry']['type'] == 'LineString': + for pt in conn_coords: + xs.append(pt[0]) + ys.append(pt[1]) + return min(xs), min(ys) + + @property + def identifier(self): + """Get or set the text string for unique object identifier.""" + return self._identifier + + @identifier.setter + def identifier(self, identifier): + self._identifier = valid_ep_string(identifier, 'identifier') + + @property + def display_name(self): + """Get or set a string for the object name without any character restrictions. + + If not set, this will be equal to the identifier. + """ + if self._display_name is None: + return self._identifier + return self._display_name + + @display_name.setter + def display_name(self, value): + try: + self._display_name = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._display_name = value # keep it as unicode + + @property + def substation(self): + """Get or set a Substation object for the network's substation.""" + return self._substation + + @substation.setter + def substation(self, value): + assert isinstance(value, Substation), \ + 'Expected Substation for electrical network. Got {}.'.format(type(value)) + self._substation = value + + @property + def transformers(self): + """Get or set the list of Transformer objects within the network.""" + return self._transformers + + @transformers.setter + def transformers(self, values): + try: + if not isinstance(values, tuple): + values = tuple(values) + except TypeError: + raise TypeError('Expected list or tuple for electrical network ' + 'transformers. Got {}'.format(type(values))) + for t in values: + assert isinstance(t, Transformer), 'Expected Transformer object' \ + ' for electrical network transformers. Got {}.'.format(type(t)) + self._transformers = values + + @property + def connectors(self): + """Get or set the list of ElectricalConnector objects within the network.""" + return self._connectors + + @connectors.setter + def connectors(self, values): + try: + if not isinstance(values, tuple): + values = tuple(values) + except TypeError: + raise TypeError('Expected list or tuple for electrical network connectors. ' + 'Got {}'.format(type(values))) + for c in values: + assert isinstance(c, ElectricalConnector), 'Expected ElectricalConnector ' \ + 'object for electrical network connectors. Got {}.'.format(type(c)) + assert len(values) > 0, 'ElectricalNetwork must possess at least one connector.' + self._connectors = values + + @property + def transformer_properties(self): + """A list of all unique TransformerProperties in the network.""" + t_props = [] + for trans in self.transformers: + if not self._instance_in_array(trans.properties, t_props): + t_props.append(trans.properties) + return list(set(t_props)) # catch duplicated/equivalent objects + + @property + def power_lines(self): + """A list of all unique PowerLines in the network.""" + power_lines = [] + for connector in self.connectors: + if not self._instance_in_array(connector.power_line, power_lines): + power_lines.append(connector.power_line) + return list(set(power_lines)) # catch duplicated/equivalent objects + + @property + def wires(self): + """A list of all unique Wires in the network.""" + wires = [] + for p_line in self.power_lines: + for wire in p_line.wires: + if not self._instance_in_array(wire, wires): + wires.append(wire) + return list(set(wires)) # catch duplicated/equivalent objects + +
    +[docs] + def junctions(self, tolerance=0.01): + """Get a list of ElectricalJunction objects for the unique network junctions. + + The resulting ElectricalJunction objects will be associated with Transformers + and Substations that they are in contact with across the network (within + the tolerance). However, they won't have any building_identifier associated + with them. The assign_junction_buildings method on this object can be used + to associate the junctions with an array of Dragonfly Buildings. + + Args: + tolerance: The minimum difference between the coordinate values of two + faces at which they can be considered centered adjacent. (Default: 0.01, + suitable for objects in meters). + + Returns: + A tuple with two items. + + - junctions - A list of lists of the unique ElectricalJunction objects + that exist across the network. + + - connector_junction_ids - A list of lists that align with the connectors + in the network. Each sub-list contains two string values for the junction + IDs for each of the start and end of each of the connectors. + """ + # loop through the connectors and find all unique junction objects + junctions, connector_junction_ids = [], [] + for connector in self.connectors: + verts = connector.geometry.vertices + end_pts, jct_ids = (verts[0], verts[-1]), [] + for jct_pt in end_pts: + for exist_jct in junctions: + if jct_pt.is_equivalent(exist_jct.geometry, tolerance): + jct_ids.append(exist_jct.identifier) + break + else: # we have found a new unique junction + new_jct_id = str(uuid.uuid4()) + junctions.append(ElectricalJunction(new_jct_id, jct_pt)) + jct_ids.append(new_jct_id) + connector_junction_ids.append(jct_ids) + + # loop through connectors and associate them with Transformers or the Substation + all_ds_objs = self.transformers + (self.substation,) + for jct in junctions: + for ds_obj in all_ds_objs: + if ds_obj.geometry.is_point_on_edge(jct.geometry, tolerance): + jct.system_identifier = ds_obj.identifier + break + return junctions, connector_junction_ids
    + + +
    +[docs] + def move(self, moving_vec): + """Move this object along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the object. + """ + self._substation.move(moving_vec) + for transformer in self.transformers: + transformer.move(moving_vec) + for connector in self.connectors: + connector.move(moving_vec)
    + + +
    +[docs] + def rotate_xy(self, angle, origin): + """Rotate this object counterclockwise in the XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._substation.rotate_xy(angle, origin) + for transformer in self.transformers: + transformer.rotate_xy(angle, origin) + for connector in self.connectors: + connector.rotate_xy(angle, origin)
    + + +
    +[docs] + def reflect(self, plane): + """Reflect this object across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will be reflected. + """ + self._substation.reflect(plane) + for transformer in self.transformers: + transformer.reflect(plane) + for connector in self.connectors: + connector.reflect(plane)
    + + +
    +[docs] + def scale(self, factor, origin=None): + """Scale this object by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + self._substation.scale(factor, origin) + for transformer in self.transformers: + transformer.scale(factor, origin) + for connector in self.connectors: + connector.scale(factor, origin)
    + + +
    +[docs] + def convert_to_units(self, units='Meters', starting_units='Meters'): + """Convert all of the geometry in this ElectricalNetwork to certain units. + + Args: + units: Text for the units to which the Model geometry should be + converted. (Default: Meters). Choose from the following: + + * Meters + * Millimeters + * Feet + * Inches + * Centimeters + + starting_units: The starting units system of the network. (Default: Meters). + """ + if starting_units != units: + scale_fac1 = conversion_factor_to_meters(starting_units) + scale_fac2 = conversion_factor_to_meters(units) + scale_fac = scale_fac1 / scale_fac2 + self.scale(scale_fac)
    + + +
    +[docs] + def to_dict(self): + """ElectricalNetwork dictionary representation.""" + base = {'type': 'ElectricalNetwork'} + base['identifier'] = self.identifier + base['substation'] = self.substation.to_dict() + base['transformers'] = [trans.to_dict(True) for trans in self.transformers] + base['connectors'] = [c.to_dict(True) for c in self.connectors] + base['transformer_properties'] = \ + [tp.to_dict() for tp in self.transformer_properties] + base['power_lines'] = [pl.to_dict(True) for pl in self.power_lines] + base['wires'] = [w.to_dict() for w in self.wires] + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, buildings, location, point=Point2D(0, 0), tolerance=0.01): + """Get ElectricalNetwork dictionary as it appears in an URBANopt geoJSON. + + The resulting dictionary array can be directly appended to the "features" + key of a base geoJSON dict in order to represent the network in the + geoJSON. Note that, in order to successfully run OpenDSS, you will also + have to write an electrical_database.json from this ElectricalNetwork using + the to_electrical_database_dict method. + + Args: + buildings: An array of Dragonfly Building objects in the same units + system as the ElectricalNetwork geometry. + location: A ladybug Location object possessing longitude and latitude data. + point: A ladybug_geometry Point2D for where the location object exists + within the space of a scene. The coordinates of this point are + expected to be in the units of this Model. (Default: (0, 0)). + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # get the conversion factors over to (longitude, latitude) + origin_lon_lat = origin_long_lat_from_location(location, point) + convert_facs = meters_to_long_lat_factors(origin_lon_lat) + + # translate substation and transformers into the geoJSON features list + features_list = [self.substation.to_geojson_dict(origin_lon_lat, convert_facs)] + for trans in self.transformers: + features_list.append(trans.to_geojson_dict(origin_lon_lat, convert_facs)) + + # translate connectors and junctions into the geoJSON features list + junctions, connector_jct_ids = self.junctions(tolerance) + for conn, jct_ids in zip(self.connectors, connector_jct_ids): + conn_dict = conn.to_geojson_dict( + jct_ids[0], jct_ids[1], origin_lon_lat, convert_facs) + features_list.append(conn_dict) + final_junctions = self.assign_junction_buildings(junctions, buildings, tolerance) + for jct in final_junctions: + features_list.append(jct.to_geojson_dict(origin_lon_lat, convert_facs)) + return features_list
    + + +
    +[docs] + def to_electrical_database_dict(self): + """Get ElectricalNetwork as it should appear in the electrical_database.json.""" + catalog_json = os.path.join( + os.path.dirname(__file__), 'lib', 'extended_catalog.json') + with open(catalog_json) as inf: + base = json.load(inf) + base['SUBSTATIONS AND DISTRIBUTION TRANSFORMERS'] = [ + { + '#Interurban:': + [tp.to_electrical_database_dict() for tp in self.transformer_properties] + } + ] + base['LINES'][1]['#Interurban Zone A:'] = \ + [pl.to_electrical_database_dict() for pl in self.power_lines] + base['WIRES']['WIRES CATALOG'] = \ + [wire.to_electrical_database_dict() for wire in self.wires] + return base
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + +
    +[docs] + @staticmethod + def assign_junction_buildings(junctions, buildings, tolerance=0.01): + """Assign building_identifiers to a list of junctions using dragonfly Buildings. + + Junctions will be assigned to a given Building if they are touching + the footprint of that building in 2D space. + + Args: + junctions: An array of ElectricalJunction objects to be associated + with Dragonfly Buildings. + buildings: An array of Dragonfly Building objects in the same units + system as the ElectricalNetwork geometry. + tolerance: The minimum difference between the coordinate values of two + geometries at which they are considered co-located. (Default: 0.01, + suitable for objects in meters). + """ + # get the footprints of the Buildings in 2D space + footprint_2d, bldg_ids = [], [] + for bldg in buildings: + footprint = bldg.footprint(tolerance) + for face3d in footprint: + pts_2d = [Point2D(pt.x, pt.y) for pt in face3d.vertices] + footprint_2d.append(Polygon2D(pts_2d)) + bldg_ids.append(bldg.identifier) + + # loop through connectors and associate them with the Buildings + for jct in junctions: + for bldg_poly, bldg_id in zip(footprint_2d, bldg_ids): + if bldg_poly.is_point_on_edge(jct.geometry, tolerance): + jct.building_identifier = bldg_id + break + return junctions
    + + + @staticmethod + def _instance_in_array(object_instance, object_array): + """Check if a specific object instance is already in an array. + + This can be much faster than `if object_instance in object_array` + when you expect to be testing a lot of the same instance of an object for + inclusion in an array since the builtin method uses an == operator to + test inclusion. + """ + for val in object_array: + if val is object_instance: + return True + return False + + def __copy__(self): + new_net = ElectricalNetwork( + self.identifier, self.substation.duplicate(), + tuple(trans.duplicate() for trans in self.transformers), + tuple(conn.duplicate() for conn in self.connectors)) + new_net._display_name = self._display_name + return new_net + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'ElectricalNetwork: {}'.format(self.display_name)
    + + + +
    +[docs] +class RoadNetwork(object): + """Represents a road network for RNM input. + + This includes a substation and roads that will be used to lay out the + road network. + + Args: + identifier: Text string for a unique road network ID. Must contain only + characters that are acceptable in RNM nad OpenDSS. This will be used to + identify the object across the exported geoJSON RNM, and OpenDSS files. + substation: A Substation object representing the road substation + supplying the network with electricity. + roads: An array of Road objects that are included within the road network. + + Properties: + * identifier + * display_name + * substation + * roads + """ + __slots__ = ('_identifier', '_display_name', '_substation', '_roads') + + def __init__(self, identifier, substation, roads): + """Initialize RoadNetwork.""" + self.identifier = identifier + self._display_name = None + self.substation = substation + self.roads = roads + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize an RoadNetwork from a dictionary. + + Args: + data: A dictionary representation of an RoadNetwork object. + """ + # check the type of dictionary + assert data['type'] == 'RoadNetwork', 'Expected RoadNetwork ' \ + 'dictionary. Got {}.'.format(data['type']) + # re-serialize geometry objects + substation = Substation.from_dict(data['substation']) + roads = [Road.from_dict(r) for r in data['roads']] + net = cls(data['identifier'], substation, roads) + if 'display_name' in data and data['display_name'] is not None: + net.display_name = data['display_name'] + return net
    + + + @property + def identifier(self): + """Get or set the text string for unique object identifier.""" + return self._identifier + + @identifier.setter + def identifier(self, identifier): + self._identifier = valid_ep_string(identifier, 'identifier') + + @property + def display_name(self): + """Get or set a string for the object name without any character restrictions. + + If not set, this will be equal to the identifier. + """ + if self._display_name is None: + return self._identifier + return self._display_name + + @display_name.setter + def display_name(self, value): + try: + self._display_name = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._display_name = value # keep it as unicode + + @property + def substation(self): + """Get or set a Substation object for the network's substation.""" + return self._substation + + @substation.setter + def substation(self, value): + assert isinstance(value, Substation), \ + 'Expected Substation for road network. Got {}.'.format(type(value)) + self._substation = value + + @property + def roads(self): + """Get or set the list of Road objects within the network.""" + return self._roads + + @roads.setter + def roads(self, values): + try: + if not isinstance(values, tuple): + values = tuple(values) + except TypeError: + raise TypeError('Expected list or tuple of roads. ' + 'Got {}'.format(type(values))) + for r in values: + assert isinstance(r, Road), 'Expected Road ' \ + 'object for road network. Got {}.'.format(type(r)) + assert len(values) > 0, 'RoadNetwork must possess at least one road.' + self._roads = values + +
    +[docs] + def move(self, moving_vec): + """Move this object along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the object. + """ + self._substation.move(moving_vec) + for road in self.roads: + road.move(moving_vec)
    + + +
    +[docs] + def rotate_xy(self, angle, origin): + """Rotate this object counterclockwise in the XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._substation.rotate_xy(angle, origin) + for road in self.roads: + road.rotate_xy(angle, origin)
    + + +
    +[docs] + def reflect(self, plane): + """Reflect this object across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will be reflected. + """ + self._substation.reflect(plane) + for road in self.roads: + road.reflect(plane)
    + + +
    +[docs] + def scale(self, factor, origin=None): + """Scale this object by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + self._substation.scale(factor, origin) + for road in self.roads: + road.scale(factor, origin)
    + + +
    +[docs] + def to_dict(self): + """RoadNetwork dictionary representation.""" + base = {'type': 'RoadNetwork'} + base['identifier'] = self.identifier + base['substation'] = self.substation.to_dict() + base['roads'] = [r.to_dict() for r in self.roads] + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, location, point=Point2D(0, 0)): + """Get RoadNetwork dictionary as it appears in an URBANopt geoJSON. + + The resulting dictionary array can be directly appended to the "features" + key of a base geoJSON dict in order to represent the network in the + geoJSON. + + Args: + location: A ladybug Location object possessing longitude and latitude data. + point: A ladybug_geometry Point2D for where the location object exists + within the space of a scene. The coordinates of this point are + expected to be in the units of this Model. (Default: (0, 0)). + """ + # get the conversion factors over to (longitude, latitude) + origin_lon_lat = origin_long_lat_from_location(location, point) + convert_facs = meters_to_long_lat_factors(origin_lon_lat) + + # translate substation and transformers into the geoJSON features list + features_list = [self.substation.to_geojson_dict(origin_lon_lat, convert_facs)] + for road in self.roads: + features_list.append(road.to_geojson_dict(origin_lon_lat, convert_facs)) + return features_list
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + new_net = RoadNetwork( + self.identifier, self.substation.duplicate(), + tuple(r.duplicate() for r in self.roads)) + new_net._display_name = self._display_name + return new_net + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'RoadNetwork: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/powerline.html b/docs/_modules/dragonfly_energy/opendss/powerline.html new file mode 100644 index 00000000..332b3aee --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/powerline.html @@ -0,0 +1,1372 @@ + + + + + + + dragonfly_energy.opendss.powerline — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.powerline

    +# coding=utf-8
    +"""PowerLine in OpenDSS."""
    +from __future__ import division
    +
    +from honeybee._lockable import lockable
    +from honeybee.typing import float_in_range, float_positive, int_positive, valid_ep_string
    +
    +from .wire import Wire
    +
    +
    +
    +[docs] +@lockable +class PowerLine(object): + """Represents the properties of a power line in OpenDSS. + + Args: + identifier: Text string for a unique wire property ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + wires: An array of Wire objects for the wires contained within the power line. + heights: An array of numbers that align with the wires and denote the height + of the wire above the ground in meters. Negative values indicate wires + below ground. + relative_xs: An array of numbers that align with the wires and denote the + X offset relative to the wire line geometry in meters. For convenience, + one of the conductors in a given wire is usually assigned the 0 position. + phases: An array of text values that align with the wires and denote the + phases of the wire. Must be one of the following values (A, B, C, N, S1, S2). + phase_count: An optional integer for the number of phases carried along the + power line. If None, it wil be inferred from the phases with only + phases A, B, C considered distinct from one another. (Default: None). + nominal_voltage: An optional number for the nominal voltage along the + power line. This is not required for OpenDSS simulation since this + value can be inferred from surrounding transformers and substations + but it it sometimes useful to assign a value directly to the + power line object. (Default: None). + + Properties: + * identifier + * display_name + * wires + * heights + * relative_xs + * phases + * phase_count + * nominal_voltage + * wire_count + * wire_ids + """ + __slots__ = ( + '_locked', '_display_name', '_identifier', '_wire_count', '_wires', '_heights', + '_relative_xs', '_phases', '_phase_count', '_nominal_voltage' + ) + VALID_PHASES = ('A', 'B', 'C', 'N', 'S1', 'S2') + + def __init__(self, identifier, wires, heights, relative_xs, phases, + phase_count=None, nominal_voltage=None): + """Initialize PowerLine""" + self._locked = False # unlocked by default + self._display_name = None + self.identifier = identifier + self._wire_count = len(wires) + assert self._wire_count > 0, 'PowerLine must possess at least one wire.' + self.wires = wires + self.heights = heights + self.relative_xs = relative_xs + self.phases = phases + self.phase_count = phase_count + self.nominal_voltage = nominal_voltage + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a PowerLine object from a dictionary. + + Args: + data: A dictionary representation of a PowerLine object in the format below. + + .. code-block:: python + + { + 'type': 'PowerLine', + 'identifier': '3P_OH_AL_ACSR_477kcmil_Hawk_12_47_0', # unique identifier + 'wires': [{}], # a list of wire definitions for the wires in the line + 'heights': [16], # height of the wire above the ground in meters + 'relative_x': [0], # number for the x offset from the wire line in meters + 'phases': ['A'] # text for the phases of the wire + } + """ + wires = [Wire.from_dict(wd) for wd in data['wires']] + pc = data['phase_count'] if 'phase_count' in data else None + vol = data['nominal_voltage'] if 'nominal_voltage' in data else None + p_line = cls(data['identifier'], wires, data['heights'], + data['relative_xs'], data['phases'], pc, vol) + if 'display_name' in data and data['display_name'] is not None: + p_line.display_name = data['display_name'] + return p_line
    + + +
    +[docs] + @classmethod + def from_dict_abridged(cls, data, wires): + """Create a PowerLine object from a dictionary. + + Args: + data: A dictionary representation of a PowerLine object in the format below. + wires: A dictionary with identifiers of wires as keys and Python + wire objects as values. + + .. code-block:: python + + { + 'type': 'PowerLine', + 'identifier': '3P_OH_AL_ACSR_477kcmil_Hawk_12_47_0', # unique identifier + 'wires': [''], # a list of wire identifiers for the wires in the line + 'heights': [16], # height of the wire above the ground in meters + 'relative_x': [0], # number for the x offset from the wire line in meters + 'phases': ['A'] # text for the phases of the wire + } + """ + try: + wires = [wires[wd] for wd in data['wires']] + except KeyError as e: + raise ValueError('Failed to find {} in wires.'.format(e)) + pc = data['phase_count'] if 'phase_count' in data else None + vol = data['nominal_voltage'] if 'nominal_voltage' in data else None + p_line = cls(data['identifier'], wires, data['heights'], + data['relative_xs'], data['phases'], pc, vol) + if 'display_name' in data and data['display_name'] is not None: + p_line.display_name = data['display_name'] + return p_line
    + + +
    +[docs] + @classmethod + def from_electrical_database_dict(cls, data, wires): + """Create a PowerLine from an dictionary as it appears in a database.json. + + Args: + data: A dictionary representation of a PowerLine object in the format below. + wires: A dictionary with identifiers of wires as keys and Python + wire objects as values. + + .. code-block:: python + + { + 'Name': '3P_OH_AL_ACSR_336kcmil_Merlin_12_47_0', # unique identifier + "Line geometry": [ + { + "wire": "OH ACSR 336kcmil", + "phase": "A", + "x (m)": 0.0, + "height (m)": 10 + }, + { + "wire": "OH ACSR 336kcmil", + "phase": "B", + "x (m)": 0.304, + "height (m)": 10 + } + ] + } + """ + try: + wire_ids = [w_i['wire'] for w_i in data['Line geometry']] + wire_objs = [wires[w_id] for w_id in wire_ids] + except KeyError as e: + raise ValueError('Failed to find {} in wires.'.format(e)) + heights = [w_i['height (m)'] for w_i in data['Line geometry']] + rel_xs = [w_i['x (m)'] for w_i in data['Line geometry']] + phases = [w_i['phase'] for w_i in data['Line geometry']] + pc = data['Nphases'] if 'Nphases' in data else None + vol = data['Voltage(kV)'] if 'Voltage(kV)' in data else None + return cls(data['Name'], wire_objs, heights, rel_xs, phases, pc, vol)
    + + + @property + def identifier(self): + """Get or set a text string for the unique object identifier.""" + return self._identifier + + @identifier.setter + def identifier(self, value): + self._identifier = valid_ep_string(value, 'power line identifier') + + @property + def display_name(self): + """Get or set a string for the object name without any character restrictions. + + If not set, this will be equal to the identifier. + """ + if self._display_name is None: + return self._identifier + return self._display_name + + @display_name.setter + def display_name(self, value): + try: + self._display_name = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._display_name = value # keep it as unicode + + @property + def wires(self): + """Get or set an array of Wire objects for the phases of the wires.""" + return self._wires + + @wires.setter + def wires(self, value): + for w in value: + assert isinstance(w, Wire), 'Expected Wire object. Got {}.'.format(type(w)) + self._wires = tuple(value) + assert len(self._wires) == self._wire_count, \ + 'Number of wires cannot be changed from {} to {}. Initialize a new ' \ + 'PowerLine object to change the number of wires.'.format( + len(self._wires), self._wire_count) + + @property + def heights(self): + """Get or set an array of numbers for the heights above the ground in meters.""" + return self._heights + + @heights.setter + def heights(self, value): + self._heights = tuple( + float_in_range(h, input_name='power line height') for h in value) + assert len(self._heights) == self._wire_count, \ + 'Number of heights [{}] does not match the number of wires [{}].'.format( + len(self._heights), self._wire_count) + + @property + def relative_xs(self): + """Get or set a array of numbers for the X offset relative to the wire in meters. + """ + return self._relative_xs + + @relative_xs.setter + def relative_xs(self, value): + self._relative_xs = tuple( + float_in_range(x, input_name='power line relative_x') for x in value) + assert len(self._relative_xs) == self._wire_count, \ + 'Number of heights [{}] does not match the number of wires [{}].'.format( + len(self._relative_xs), self._wire_count) + + @property + def phases(self): + """Get or set an array of text for the phases of the wires.""" + return self._phases + + @phases.setter + def phases(self, value): + for p in value: + assert p in self.VALID_PHASES, 'Phase "{}" is not acceptable. ' \ + 'Choose from the following:\n{}'.format(p, '\n'.join(self.VALID_PHASES)) + self._phases = tuple(value) + assert len(self._phases) == self._wire_count, \ + 'Number of heights [{}] does not match the number of wires [{}].'.format( + len(self._phases), self._wire_count) + + @property + def phase_count(self): + """Get or set an integer for the number of phases carried along the line.""" + if self._phase_count is not None: + return self._phase_count + all_phases = [p for p in self._phases if p in ('A', 'B', 'C')] + return len(all_phases) if len(all_phases) != 0 else 1 + + @phase_count.setter + def phase_count(self, value): + if value is not None: + value = int_positive(value, 'power line phase count') + self._phase_count = value + + @property + def nominal_voltage(self): + """Get or set a number for nominal voltage of the power line in kiloVolts.""" + return self._nominal_voltage + + @nominal_voltage.setter + def nominal_voltage(self, value): + if value is not None: + value = float_positive(value, 'nominal voltage') + self._nominal_voltage = value + + @property + def wire_count(self): + """Get an integer for the number of wires in the power line.""" + return self._wire_count + + @property + def wire_ids(self): + """Get a list of wire identifiers in the power line.""" + return [wire.identifier for wire in self._wires] + +
    +[docs] + def to_dict(self, abridged=False): + """Get PowerLine dictionary. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True), + which only specifies the identifiers of wires. (Default: False). + """ + base = {'type': 'PowerLine'} if not abridged else {'type': 'PowerLineAbridged'} + base['identifier'] = self.identifier + base['wires'] = self.wire_ids if abridged else [w.to_dict() for w in self.wires] + base['heights'] = self.heights + base['relative_xs'] = self.relative_xs + base['phases'] = self.phases + if self._phase_count is not None: + base['phase_count'] = self._phase_count + if self._nominal_voltage is not None: + base['nominal_voltage'] = self._nominal_voltage + if self._display_name is not None: + base['display_name'] = self._display_name + return base
    + + +
    +[docs] + def to_electrical_database_dict(self): + """Get Wire as it should appear in the URBANopt database.json.""" + base = {'Name': self.identifier} + line_geo = [] + all_props = zip(self.wires, self.heights, self.relative_xs, self.phases) + for wire, hgt, r_x, pha in all_props: + w_dict = { + 'wire': wire.identifier, + 'phase': pha, + 'x (m)': r_x, + 'height (m)': hgt + } + line_geo.append(w_dict) + base['Line geometry'] = line_geo + if self._phase_count is not None: + base['Nphases'] = self._phase_count + if self._nominal_voltage is not None: + base['Voltage(kV)'] = self._nominal_voltage + return base
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + new_obj = PowerLine( + self.identifier, self.wires, self.heights, self.relative_xs, self.phases, + self._phase_count, self._nominal_voltage) + new_obj._display_name = self._display_name + return new_obj + + def __key(self): + """A tuple based on the object properties, useful for hashing.""" + return (self.identifier,) + tuple(hash(w) for w in self.wires) + \ + self.heights + self.relative_xs + self.phases + \ + (self._phase_count, self._nominal_voltage) + + def __hash__(self): + return hash(self.__key()) + + def __eq__(self, other): + return isinstance(other, PowerLine) and self.__key() == other.__key() + + def __ne__(self, other): + return not self.__eq__(other) + + def __len__(self): + return len(self._wires) + + def __getitem__(self, key): + return self._wires[key] + + def __iter__(self): + return iter(self._wires) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent wire.""" + return 'PowerLine: {}'.format(self.identifier)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/result.html b/docs/_modules/dragonfly_energy/opendss/result.html new file mode 100644 index 00000000..6d01bdb0 --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/result.html @@ -0,0 +1,1121 @@ + + + + + + + dragonfly_energy.opendss.result — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.result

    +"""Module for parsing OpenDSS results to data collections."""
    +import os
    +import datetime
    +
    +from ladybug.datacollection import HourlyContinuousCollection
    +from ladybug.header import Header
    +from ladybug.analysisperiod import AnalysisPeriod
    +from ladybug.datatype.generic import GenericType
    +from ladybug.datatype.fraction import Fraction
    +from ladybug.futil import csv_to_matrix
    +
    +
    +
    +[docs] +class OpenDSSResult(object): + """Object for parsing OpenDSS CSV result files into Ladybug DataCollections. + + Args: + file_paths: A list of file paths to CSV files that were generated by OpenDSS. + + Properties: + * file_paths + * factor_data + * condition_data + * peak_factors + * average_factors + """ + # data types for the various outputs from OpenDSS + IS_OVERLOADED = GenericType( + 'Is Overloaded', 'condition', + unit_descr={1: 'Overloaded', 0: 'Normal'}) + VOLTAGE_CONDITION = GenericType( + 'Voltage Condition', 'condition', + unit_descr={-1: 'Undervoltage', 0: 'Normal', 1: 'Overvoltage'}) + + def __init__(self, file_paths): + """Initialize OpenDSSResult""" + # check the file paths + for fp in file_paths: + assert os.path.isfile(fp), 'No file was found at {}'.format(fp) + assert fp.endswith('.csv'), \ + '{} is not an SQL file ending in .sql or .db.'.format(fp) + self._file_paths = tuple(file_paths) + + # parse the csv data + factors, condition = [], [] + for result_file in self._file_paths: + # parse the data and figure out the time series properties + data = csv_to_matrix(result_file) + data.pop(0) # remove the header from the CSV column + a_period = self._extract_analysis_period(data) + + # figure out the type of object to write into the metadata + obj_name = os.path.basename(result_file).replace('.csv', '') + if obj_name.startswith('Line.'): + obj_name = obj_name.replace('Line.', '') + obj_type = 'Electrical Connector Loading' + elif obj_name.startswith('Transformer.'): + obj_name = obj_name.replace('Transformer.', '') + obj_type = 'Transformer Loading' + else: + obj_type = 'Building Voltage' + metadata = {'type': obj_type, 'name': obj_name} + + # output the data collection of factors + result_vals = [float(data[i][1]) for i in range(len(data))] + header = Header(Fraction('Loading Factor'), 'fraction', a_period, metadata) + factors.append(HourlyContinuousCollection(header, result_vals)) + + # output the data collection of conditions + if len(data[0]) == 4: # building voltage results + cond_vals = [] + for row in data: + cond = 0 if row[2] == 'False' else 1 + if cond != 1 and row[3] == 'True\n': + cond = -1 + cond_vals.append(cond) + header = Header( + self.VOLTAGE_CONDITION, self.VOLTAGE_CONDITION.units[0], + a_period, metadata) + condition.append(HourlyContinuousCollection(header, cond_vals)) + else: # transformer or connector load + cond_vals = [] + for row in data: + cond = 0 if row[2] == 'False\n' else 1 + cond_vals.append(cond) + header = Header( + self.IS_OVERLOADED, self.IS_OVERLOADED.units[0], + a_period, metadata) + condition.append(HourlyContinuousCollection(header, cond_vals)) + self._factor_data = tuple(factors) + self._condition_data = tuple(condition) + + @property + def file_paths(self): + """Get a tuple of file paths to CSV files.""" + return self._file_paths + + @property + def factor_data(self): + """Get a tuple of loading factors associated with the input file paths.""" + return self._factor_data + + @property + def condition_data(self): + """Get a tuple of conditions associated with the input file paths.""" + return self._condition_data + + @property + def peak_factors(self): + """Get a list of numbers for the peak factors across the data.""" + return [dat.max for dat in self._factor_data] + + @property + def average_factors(self): + """Get a list of numbers for the average factors across the data.""" + return [dat.average for dat in self._factor_data] + + @staticmethod + def _date_str_to_datetime(date_str): + """Get a datetime object from a string.""" + return datetime.datetime.strptime(date_str, '%Y/%m/%d %H:%M:%S') + + @staticmethod + def _extract_analysis_period(data): + """Extract an AnalysisPeriod from CSV data.""" + dts = [OpenDSSResult._date_str_to_datetime(data[i][0]) for i in (0, 1, -2)] + timestep = int(3600 / (dts[1] - dts[0]).total_seconds()) + leap_year = True if dts[0].year % 4 == 0 else False + a_period = AnalysisPeriod( + dts[0].month, dts[0].day, 0, dts[-1].month, dts[-1].day, 23, + timestep=timestep, is_leap_year=leap_year) + return a_period + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString.""" + return self.__repr__()
    + + + def __repr__(self): + return 'OpenDSS Result [{} files]'.format(len(self.file_paths))
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/road.html b/docs/_modules/dragonfly_energy/opendss/road.html new file mode 100644 index 00000000..f2e7034a --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/road.html @@ -0,0 +1,1093 @@ + + + + + + + dragonfly_energy.opendss.road — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.road

    +# coding=utf-8
    +"""Road along which RNM will place electrical connectors."""
    +from __future__ import division
    +
    +from ladybug_geometry.geometry2d.line import LineSegment2D
    +from ladybug_geometry.geometry2d.polyline import Polyline2D
    +from dragonfly.projection import polygon_to_lon_lat
    +
    +from .._base import _GeometryBase
    +
    +
    +
    +[docs] +class Road(_GeometryBase): + """Represents a road along which RNM will place electrical connectors. + + Args: + identifier: Text string for a unique road ID. Must contain only characters + that are acceptable in RNM and OpenDSS. This will be used to + identify the object across the exported geoJSON, RNM and OpenDSS files. + geometry: A LineSegment2D or Polyline2D representing the geometry of the road. + + Properties: + * identifier + * display_name + * geometry + """ + __slots__ = () + + def __init__(self, identifier, geometry): + """Initialize Road.""" + _GeometryBase.__init__(self, identifier) # process the identifier + assert isinstance(geometry, (LineSegment2D, Polyline2D)), 'Expected ' \ + 'ladybug_geometry LineSegment2D or Polyline2D. Got {}'.format(type(geometry)) + self._geometry = geometry + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize a Road from a dictionary. + + Args: + data: A dictionary representation of a Road object. + """ + # check the type of dictionary + assert data['type'] == 'Road', 'Expected Road ' \ + 'dictionary. Got {}.'.format(data['type']) + geo = LineSegment2D.from_dict(data['geometry']) \ + if data['geometry']['type'] == 'LineSegment2D' \ + else Polyline2D.from_dict(data['geometry']) + road = cls(data['identifier'], geo) + if 'display_name' in data and data['display_name'] is not None: + road.display_name = data['display_name'] + return road
    + + + @property + def geometry(self): + """Get a LineSegment2D or Polyline2D representing the road geometry.""" + return self._geometry + +
    +[docs] + def to_dict(self): + """Road dictionary representation.""" + base = {'type': 'Road'} + base['identifier'] = self.identifier + base['geometry'] = self.geometry.to_dict() + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, origin_lon_lat, conversion_factors): + """Get Road dictionary as it appears in an URBANopt geoJSON. + + Args: + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + if isinstance(self.geometry, LineSegment2D): + pts = [(pt.x, pt.y) for pt in (self.geometry.p1, self.geometry.p2)] + else: # it's a polyline + pts = [(pt.x, pt.y) for pt in self.geometry.vertices] + coords = polygon_to_lon_lat(pts, origin_lon_lat, conversion_factors) + return { + 'type': 'Feature', + 'properties': { + 'id': self.identifier, + 'type': 'Road', + 'total_length': round(self.geometry.length, 1), + 'name': self.display_name + }, + 'geometry': { + 'type': 'LineString', + 'coordinates': coords + } + }
    + + + def __copy__(self): + new_con = Road(self.identifier, self.geometry) + new_con._display_name = self._display_name + return new_con + + def __repr__(self): + return 'Road: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/substation.html b/docs/_modules/dragonfly_energy/opendss/substation.html new file mode 100644 index 00000000..7a71803b --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/substation.html @@ -0,0 +1,1111 @@ + + + + + + + dragonfly_energy.opendss.substation — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.substation

    +# coding=utf-8
    +"""Electrical substation in OpenDSS."""
    +from .._base import _GeometryBase
    +
    +from ladybug_geometry.geometry2d.polygon import Polygon2D
    +from dragonfly.projection import polygon_to_lon_lat
    +
    +
    +
    +[docs] +class Substation(_GeometryBase): + """Represents a substation in OpenDSS. + + Args: + identifier: Text string for a unique electrical substation ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + geometry: A Polygon2D representing the geometry of the electrical substation. + + Properties: + * identifier + * display_name + * geometry + """ + __slots__ = () + + def __init__(self, identifier, geometry): + """Initialize Substation.""" + _GeometryBase.__init__(self, identifier) # process the identifier + assert isinstance(geometry, Polygon2D), 'Expected ladybug_geometry ' \ + 'Polygon2D for Substation geometry. Got {}'.format(type(geometry)) + self._geometry = geometry + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize a Substation from a dictionary. + + Args: + data: A dictionary representation of an Substation object. + """ + # check the type of dictionary + assert data['type'] == 'Substation', 'Expected Substation ' \ + 'dictionary. Got {}.'.format(data['type']) + geo = Polygon2D.from_dict(data['geometry']) + trans = cls(data['identifier'], geo) + if 'display_name' in data and data['display_name'] is not None: + trans.display_name = data['display_name'] + return trans
    + + +
    +[docs] + @classmethod + def from_rnm_geojson_dict( + cls, data, origin_lon_lat, conversion_factors): + """Get a Substation from a dictionary as it appears in an RNM GeoJSON. + + Args: + data: A GeoJSON dictionary representation of an Substation feature. + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + geo = cls._geojson_coordinates_to_polygon2d( + data['geometry']['coordinates'], origin_lon_lat, conversion_factors) + return cls(data['properties']['Code'], geo)
    + + + @property + def geometry(self): + """Get a Polygon2D representing the substation.""" + return self._geometry + +
    +[docs] + def to_dict(self): + """Substation dictionary representation.""" + base = {'type': 'Substation'} + base['identifier'] = self.identifier + base['geometry'] = self.geometry.to_dict() + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, origin_lon_lat, conversion_factors): + """Get Substation dictionary as it appears in an URBANopt geoJSON. + + Args: + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + pts = [(pt.x, pt.y) for pt in self.geometry.vertices] + coords = [polygon_to_lon_lat(pts, origin_lon_lat, conversion_factors)] + coords[0].append(coords[0][0]) + return { + 'type': 'Feature', + 'properties': { + 'id': self.identifier, + 'geometryType': 'Rectangle', + 'name': self.display_name, + 'type': 'District System', + 'footprint_area': round(self.geometry.area, 1), + 'footprint_perimeter': round(self.geometry.perimeter, 1), + 'district_system_type': 'Electrical Substation', + }, + 'geometry': { + 'type': 'Polygon', + 'coordinates': coords + } + }
    + + + def __copy__(self): + new_con = Substation(self.identifier, self.geometry) + new_con._display_name = self._display_name + return new_con + + def __repr__(self): + return 'Substation: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/transformer.html b/docs/_modules/dragonfly_energy/opendss/transformer.html new file mode 100644 index 00000000..26fb1db3 --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/transformer.html @@ -0,0 +1,1189 @@ + + + + + + + dragonfly_energy.opendss.transformer — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.transformer

    +# coding=utf-8
    +"""Electrical transformer in OpenDSS."""
    +from __future__ import division
    +
    +from .._base import _GeometryBase
    +from .transformerprop import TransformerProperties
    +
    +from ladybug_geometry.geometry2d.polygon import Polygon2D
    +from dragonfly.projection import polygon_to_lon_lat
    +
    +
    +
    +[docs] +class Transformer(_GeometryBase): + """Represents a transformer in OpenDSS. + + Args: + identifier: Text string for a unique electrical transformer ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + geometry: A Polygon2D representing the geometry of the electrical transformer. + properties: A TransformerProperties object representing the properties of + the electrical transformer. + + Properties: + * identifier + * display_name + * geometry + * properties + * phase_count + * nominal_voltage + """ + __slots__ = ('_properties',) + + def __init__(self, identifier, geometry, properties): + """Initialize Transformer.""" + _GeometryBase.__init__(self, identifier) # process the identifier + assert isinstance(geometry, Polygon2D), 'Expected ladybug_geometry ' \ + 'Polygon2D for Transformer geometry. Got {}'.format(type(geometry)) + self._geometry = geometry + self.properties = properties + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize an Transformer from a dictionary. + + Args: + data: A dictionary representation of an Transformer object. + """ + assert data['type'] == 'Transformer', 'Expected Transformer ' \ + 'dictionary. Got {}.'.format(data['type']) + props = TransformerProperties.from_dict(data['properties']) + geo = Polygon2D.from_dict(data['geometry']) + trans = cls(data['identifier'], geo, props) + if 'display_name' in data and data['display_name'] is not None: + trans.display_name = data['display_name'] + return trans
    + + +
    +[docs] + @classmethod + def from_dict_abridged(cls, data, properties): + """Initialize a Transformer from an abridged dictionary. + + Args: + data: A TransformerAbridged dictionary. + properties: A dictionary with identifiers of TransformerProperties + as keys and Python TransformerProperties objects as values. + """ + assert data['type'] == 'TransformerAbridged', \ + 'Expected TransformerAbridged. Got {}.'.format(data['type']) + try: + props = properties[data['properties']] + except KeyError as e: + raise ValueError('Failed to find "{}" in properties.'.format(e)) + geo = Polygon2D.from_dict(data['geometry']) + trans = cls(data['identifier'], geo, props) + if 'display_name' in data and data['display_name'] is not None: + trans.display_name = data['display_name'] + return trans
    + + +
    +[docs] + @classmethod + def from_rnm_geojson_dict( + cls, data, origin_lon_lat, conversion_factors): + """Get a Transformer from a dictionary as it appears in an RNM GeoJSON. + + Args: + data: A GeoJSON dictionary representation of an Transformer feature. + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + geo = cls._geojson_coordinates_to_polygon2d( + data['geometry']['coordinates'], origin_lon_lat, conversion_factors) + prop = data['properties'] + kva_rating = 100 if 'Snom' not in prop else prop['Snom'] + resis = 0.1 if 'LV_R(ohm)' not in prop else prop['LV_R(ohm)'] + t_props = TransformerProperties( + prop['Code'], kva_rating, resistance=resis, + reactance=prop['Xsc(pu)'], phase_count=prop['Phases'], + high_voltage=prop['Vnom1'], low_voltage=prop['Vnom2']) + return cls(prop['Code'], geo, t_props)
    + + + @property + def geometry(self): + """Get a Polygon2D representing the transformer.""" + return self._geometry + + @property + def properties(self): + """Get or set a TransformerProperties object for the transformer.""" + return self._properties + + @properties.setter + def properties(self, value): + assert isinstance(value, TransformerProperties), \ + 'Expected TransformerProperties object' \ + ' for transformer properties. Got {}.'.format(type(value)) + value.lock() + self._properties = value + + @property + def phase_count(self): + """Get an integer for the number of phases this transformer supports.""" + return self._properties.phase_count + + @property + def nominal_voltage(self): + """Get an integer for the higher voltage of this transformer.""" + return self._properties.high_voltage + +
    +[docs] + def to_dict(self, abridged=False): + """Transformer dictionary representation. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True), + which only specifies the identifiers of properties. (Default: False). + """ + base = {'type': 'Transformer'} if not \ + abridged else {'type': 'TransformerAbridged'} + base['identifier'] = self.identifier + base['geometry'] = self.geometry.to_dict() + base['properties'] = self.properties.to_dict() if not abridged \ + else self.properties.identifier + if self._display_name is not None: + base['display_name'] = self.display_name + return base
    + + +
    +[docs] + def to_geojson_dict(self, origin_lon_lat, conversion_factors): + """Get Transformer dictionary as it appears in an URBANopt geoJSON. + + Args: + origin_lon_lat: An array of two numbers in degrees. The first value + represents the longitude of the scene origin in degrees (between -180 + and +180). The second value represents latitude of the scene origin + in degrees (between -90 and +90). Note that the "scene origin" is the + (0, 0) coordinate in the 2D space of the input polygon. + conversion_factors: A tuple with two values used to translate between + meters and longitude, latitude. + """ + pts = [(pt.x, pt.y) for pt in self.geometry.vertices] + coords = [polygon_to_lon_lat(pts, origin_lon_lat, conversion_factors)] + coords[0].append(coords[0][0]) + base = { + 'type': 'Feature', + 'properties': { + 'id': self.identifier, + 'geometryType': 'Rectangle', + 'name': self.display_name, + 'type': 'District System', + 'footprint_area': round(self.geometry.area, 1), + 'footprint_perimeter': round(self.geometry.perimeter, 1), + 'district_system_type': 'Transformer', + 'electrical_catalog_name': self.properties.identifier + }, + 'geometry': { + 'type': 'Polygon', + 'coordinates': coords + } + } + if self.properties.phase_count == 3: + base['properties']['phases'] = ['A', 'B', 'C'] + elif self.properties.phase_count == 1: + base['properties']['phases'] = ['A'] + return base
    + + + def __copy__(self): + new_con = Transformer(self.identifier, self.geometry, self.properties) + new_con._display_name = self._display_name + return new_con + + def __repr__(self): + return 'Transformer: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/transformerprop.html b/docs/_modules/dragonfly_energy/opendss/transformerprop.html new file mode 100644 index 00000000..a33fe098 --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/transformerprop.html @@ -0,0 +1,1298 @@ + + + + + + + dragonfly_energy.opendss.transformerprop — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.transformerprop

    +# coding=utf-8
    +"""Transformer properties in OpenDSS."""
    +from __future__ import division
    +
    +from honeybee._lockable import lockable
    +from honeybee.typing import float_positive, int_in_range, valid_ep_string
    +
    +
    +
    +[docs] +@lockable +class TransformerProperties(object): + """Represents the properties of a Transformer in OpenDSS. + + Args: + identifier: Text string for a unique wire property ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + kva: Base kVA rating of the transformer in kiloVolt-Amps. + resistance: A number for the electrical resistance of the transformer + in ohms. (Default: 0.1). + reactance: A number for the electrical reactance of the transformer + in per-unit values (p.u. transf). (Default: 0.1). + phase_count: An integer for the number of phases in the transformer. Typically, + this is either 1 or 3. (Default: 3). + high_voltage: A number for the high voltage of the transformer in + kiloVolts. (Default: 13.2). + low_voltage: A number for the low voltage of the transformer in + kiloVolts. (Default: 0.48). + is_center_tap: Boolean for whether the transformer is center-tapped + (True) or not (False). (Default: False). + connection: Text for the type of internal connection in the transformer, either + "Wye-Wye", "Wye-Delta", "Delta-Wye" or "Delta-Delta". (Default: "Wye-Wye"). + + Properties: + * identifier + * display_name + * kva + * resistance + * reactance + * phase_count + * high_voltage + * low_voltage + * is_center_tap + * connection + """ + __slots__ = ( + '_locked', '_display_name', '_identifier', '_kva', '_resistance', '_reactance', + '_phase_count', '_high_voltage', '_low_voltage', '_is_center_tap', '_connection') + + VALID_CONNECTIONS = ('Wye-Wye', 'Wye-Delta', 'Delta-Wye', 'Delta-Delta') + + def __init__(self, identifier, kva, resistance=0.1, reactance=0.1, + phase_count=3, high_voltage=13.2, low_voltage=0.48, + is_center_tap=False, connection='Wye-Wye'): + """Initialize TransformerProperties""" + self._locked = False # unlocked by default + self._display_name = None + self.identifier = identifier + self.kva = kva + self.resistance = resistance + self.reactance = reactance + self.phase_count = phase_count + self.high_voltage = high_voltage + self.low_voltage = low_voltage + self.is_center_tap = is_center_tap + self.connection = connection + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a TransformerProperties object from a dictionary. + + Args: + data: A dictionary representation of a TransformerProperties object + in the format below. + + .. code-block:: python + + { + 'type': 'TransformerProperties', + 'identifier': 'Transformer--50KVA PM', # unique identifier + 'kva': 50, # kVA rating of the transformer + 'resistance': 0.1, # transformer resistance in ohms + 'reactance': 0.1, # transformer reactance in ohms + 'phase_count': 3, # number of transformer phases + 'high_voltage': 13.2, # transformer high voltage in kV + 'low_voltage': 0.48, # transformer low voltage in kV + 'is_center_tap': False, # boolean for if the transformer is center-tapped + 'connection': 'Wye-Wye' # text for the type of connection + } + """ + resistance = data['resistance'] if 'resistance' in data else 0.1 + reactance = data['reactance'] if 'reactance' in data else 0.1 + phases = data['phase_count'] if 'phase_count' in data else 3 + hv = data['high_voltage'] if 'high_voltage' in data else 13.2 + lv = data['low_voltage'] if 'low_voltage' in data else 0.48 + icp = data['is_center_tap'] if 'is_center_tap' in data else False + con = data['connection'] if 'connection' in data else 'Wye-Wye' + wire = cls(data['identifier'], data['kva'], resistance, reactance, + phases, hv, lv, icp, con) + if 'display_name' in data and data['display_name'] is not None: + wire.display_name = data['display_name'] + return wire
    + + +
    +[docs] + @classmethod + def from_electrical_database_dict(cls, data): + """Create from a dictionary as it appears in electrical_database.json. + + Args: + data: A dictionary representation of an TransformerProperties object + in the format below. + + .. code-block:: python + + { + 'Name': 'MAT_1I_230_69', # unique identifier + 'Installed Power(kVA)': 50, # kVA rating of the transformer + 'Low-voltage-side short-circuit resistance (ohms)': 0.1, # resistance (ohms) + 'Reactance (p.u. transf)': 0.1, # transformer reactance in ohms + 'Nphases': 3, # number of transformer phases + 'Primary Voltage (kV)': 13.2, # transformer high voltage in kV + 'Secondary Voltage (kV)': 0.48, # transformer low voltage in kV + 'Centertap': False, # boolean for if the transformer is center-tapped + 'connection': 'Wye-Wye' # text for the type of connection + } + """ + return cls( + data['Name'], data['Installed Power(kVA)'], + data['Low-voltage-side short-circuit resistance (ohms)'], + data['Reactance (p.u. transf)'], data['Nphases'], + data['Primary Voltage (kV)'], data['Secondary Voltage (kV)'], + data['Centertap'], data['connection'])
    + + + @property + def identifier(self): + """Get or set a text string for the unique object identifier.""" + return self._identifier + + @identifier.setter + def identifier(self, value): + self._identifier = valid_ep_string(value, 'transformer properties identifier') + + @property + def display_name(self): + """Get or set a string for the object name without any character restrictions. + + If not set, this will be equal to the identifier. + """ + if self._display_name is None: + return self._identifier + return self._display_name + + @display_name.setter + def display_name(self, value): + try: + self._display_name = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._display_name = value # keep it as unicode + + @property + def kva(self): + """Get or set a number for the base kVA rating of the transformer in kVA.""" + return self._kva + + @kva.setter + def kva(self, value): + self._kva = float_positive(value, input_name='kva') + + @property + def resistance(self): + """Get or set a number for the resistance of the transformer in ohms.""" + return self._resistance + + @resistance.setter + def resistance(self, value): + self._resistance = float_positive(value, 'resistance') + + @property + def reactance(self): + """Get or set a number for the reactance of the transformer in p.u. transf.""" + return self._reactance + + @reactance.setter + def reactance(self, value): + self._reactance = float_positive(value, 'reactance') + + @property + def phase_count(self): + """Get or set an integer for the number of phases of the transformer.""" + return self._phase_count + + @phase_count.setter + def phase_count(self, value): + self._phase_count = int_in_range(value, 1, 3, 'transformer phase count') + + @property + def high_voltage(self): + """Get or set a number for the high voltage of the transformer in kiloVolts.""" + return self._high_voltage + + @high_voltage.setter + def high_voltage(self, value): + self._high_voltage = float_positive(value, 'high voltage') + + @property + def low_voltage(self): + """Get or set a number for the low voltage of the transformer in kiloVolts.""" + return self._low_voltage + + @low_voltage.setter + def low_voltage(self, value): + self._low_voltage = float_positive(value, 'low voltage') + + @property + def is_center_tap(self): + """Get or set a boolean for whether the transformer is center-tapped.""" + return self._is_center_tap + + @is_center_tap.setter + def is_center_tap(self, value): + self._is_center_tap = bool(value) + + @property + def connection(self): + """Get or set text for the type of internal connection in the transformer.""" + return self._connection + + @connection.setter + def connection(self, value): + assert value in self.VALID_CONNECTIONS, 'Phase "{}" is not acceptable. ' \ + 'Choose from the following:\n{}'.format( + value, '\n'.join(self.VALID_CONNECTIONS)) + self._connection = value + +
    +[docs] + def to_dict(self): + """Get TransformerProperties dictionary.""" + base = { + 'type': 'TransformerProperties', + 'identifier': self.identifier, + 'kva': self.kva, + 'resistance': self.resistance, + 'reactance': self.reactance, + 'phase_count': self.phase_count, + 'high_voltage': self.high_voltage, + 'low_voltage': self.low_voltage, + 'is_center_tap': self.is_center_tap, + 'connection': self.connection} + if self._display_name is not None: + base['display_name'] = self._display_name + return base
    + + +
    +[docs] + def to_electrical_database_dict(self): + """Get Wire as it should appear in the URBANopt electrical_database.json.""" + return { + 'Name': self.identifier, + 'Type': 'I', + 'Voltage level': 'MV-LV', + 'Installed Power(kVA)': self.kva, + 'Guaranteed Power(kVA)': self.kva, + 'Low-voltage-side short-circuit resistance (ohms)': self.resistance, + 'Reactance (p.u. transf)': self.reactance, + 'Nphases': self.phase_count, + 'Primary Voltage (kV)': self.high_voltage, + 'Secondary Voltage (kV)': self.low_voltage, + 'Centertap': self.is_center_tap, + 'connection': self.connection + }
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + new_obj = TransformerProperties( + self.identifier, self.kva, self.resistance, self.reactance, self.phase_count, + self.high_voltage, self.low_voltage, self.is_center_tap, self.connection) + new_obj._display_name = self._display_name + return new_obj + + def __key(self): + """A tuple based on the object properties, useful for hashing.""" + return ( + self.identifier, self.kva, self.resistance, self.reactance, + self.phase_count, self.high_voltage, self.low_voltage, + self.is_center_tap, self.connection) + + def __hash__(self): + return hash(self.__key()) + + def __eq__(self, other): + return isinstance(other, TransformerProperties) and self.__key() == other.__key() + + def __ne__(self, other): + return not self.__eq__(other) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent TransformerProperties.""" + return 'TransformerProperties: {}'.format(self.identifier)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/opendss/wire.html b/docs/_modules/dragonfly_energy/opendss/wire.html new file mode 100644 index 00000000..5eb3626e --- /dev/null +++ b/docs/_modules/dragonfly_energy/opendss/wire.html @@ -0,0 +1,1503 @@ + + + + + + + dragonfly_energy.opendss.wire — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.opendss.wire

    +# coding=utf-8
    +"""Wire in OpenDSS."""
    +from __future__ import division
    +
    +from honeybee._lockable import lockable
    +from honeybee.typing import float_positive, int_positive, valid_ep_string
    +
    +
    +
    +[docs] +@lockable +class Wire(object): + """Represents the properties of a wire in OpenDSS. + + Args: + identifier: Text string for a unique wire property ID. Must contain only + characters that are acceptable in OpenDSS. This will be used to + identify the object across the exported geoJSON and OpenDSS files. + ampacity: A number for the ampacity of the wire in amps. (Default: 220). + geometrical_mean_radius: A number for the geometric mean of distances between + the strands of the conductor in millimeters. (Default: 3.9). + resistance: A number for the electrical resistance of the conductor in + ohms per kilometer of wire. (Default: 0.3937). + diameter: A number for the diameter of the wire in millimeters. (Default: 10). + voltage_level: Text to denote the level of voltage that the wire is designed to + carry. Choose from ("LV", "MV", "LV or MV"). (Default: "MV"). + wire_type: Text for the type of wire, denoting whether the wire is overhead + (OH) or underground (UG). Choose from ('OH', 'UG', 'UG concentric + neutral'). (Default: "OH"). + concentric_properties: A ConcentricProperties object to denote the concentric + neutral properties of the Wire. This must be specified when the wire_type + is "UG concentric neutral." (Default: None). + + Properties: + * identifier + * display_name + * ampacity + * geometrical_mean_radius + * resistance + * diameter + * voltage_level + * wire_type + * concentric_properties + """ + __slots__ = ( + '_locked', '_display_name', '_identifier', '_ampacity', + '_geometrical_mean_radius', '_resistance', '_diameter', + '_voltage_level', '_wire_type', '_concentric_properties' + ) + + VALID_VOLTAGE_LEVELS = ('LV', 'MV', 'LV or MV') + VALID_WIRE_TYPES = ('OH', 'UG', 'UG concentric neutral') + + def __init__(self, identifier, ampacity=220, geometrical_mean_radius=3.9, + resistance=0.3937, diameter=10, voltage_level='MV', + wire_type='OH', concentric_properties=None): + """Initialize Wire""" + self._locked = False # unlocked by default + self._display_name = None + self.identifier = identifier + self.ampacity = ampacity + self.geometrical_mean_radius = geometrical_mean_radius + self.resistance = resistance + self.diameter = diameter + self.voltage_level = voltage_level + self.concentric_properties = concentric_properties + self.wire_type = wire_type + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a Wire object from a dictionary. + + Args: + data: A dictionary representation of a Wire object in the format below. + + .. code-block:: python + + { + 'type': 'Wire', + 'identifier': 'OH AL 2/0 A', # unique wire property identifier + 'ampacity': 220, # ampacity of the wire in amps + 'geometrical_mean_radius': 3.9, # gmr in mm + 'resistance': 0.3937, # resistance of the wire in ohms/km + 'diameter': 10, # diameter of the wire in mm + 'voltage_level': 'LV or MV', # text for the voltage level + 'wire_type': 'OH' # text for the type of wire + } + """ + amp = data['ampacity'] if 'ampacity' in data else 220 + gmr = data['geometrical_mean_radius'] if 'geometrical_mean_radius' in data \ + else 3.9 + res = data['resistance'] if 'resistance' in data else 0.3937 + dim = data['diameter'] if 'diameter' in data else 10 + vl = data['voltage_level'] if 'voltage_level' in data else 'MV' + wt = data['wire_type'] if 'wire_type' in data else 'OH' + c_prop = ConcentricProperties.from_dict(data['concentric_properties']) \ + if 'concentric_properties' in data and \ + data['concentric_properties'] is not None else None + wire = cls(data['identifier'], amp, gmr, res, dim, vl, wt, c_prop) + if 'display_name' in data and data['display_name'] is not None: + wire.display_name = data['display_name'] + return wire
    + + +
    +[docs] + @classmethod + def from_electrical_database_dict(cls, data): + """Create a Wire from an dictionary as it appears in electrical_database.json. + + Args: + data: A dictionary representation of a Wire object in the format below. + + .. code-block:: python + + { + 'nameclass': 'OH AL 2/0 A', # unique wire property identifier + 'ampacity (A)': 220, # ampacity of the wire in amps + 'gmr (mm)': 3.9, # gmr in meters + 'resistance (ohm/km)': 0.3937, # resistance of the wire in ohms/km + 'diameter (mm)': 10, # diameter of the wire in meters + 'voltage level': 'MV', + 'type': 'OH' + } + """ + c_prop = None + if data['type'] == 'UG concentric neutral': + c_prop = ConcentricProperties( + data['gmr neutral (mm)'], + data['resistance neutral (ohm/km)'], + data['concentric diameter neutral strand (mm)'], + data['concentric neutral outside diameter (mm)'], + data['# concentric neutral strands'] + ) + return cls( + data['nameclass'], data['ampacity (A)'], data['gmr (mm)'], + data['resistance (ohm/km)'], data['diameter (mm)'], + data['voltage level'], data['type'], c_prop)
    + + + @property + def identifier(self): + """Get or set a text string for the unique object identifier.""" + return self._identifier + + @identifier.setter + def identifier(self, value): + self._identifier = valid_ep_string(value, 'wire identifier') + + @property + def display_name(self): + """Get or set a string for the object name without any character restrictions. + + If not set, this will be equal to the identifier. + """ + if self._display_name is None: + return self._identifier + return self._display_name + + @display_name.setter + def display_name(self, value): + try: + self._display_name = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._display_name = value # keep it as unicode + + @property + def ampacity(self): + """Get or set a number for the ampacity of the wire in amps.""" + return self._ampacity + + @ampacity.setter + def ampacity(self, value): + self._ampacity = float_positive(value, 'ampacity') + + @property + def geometrical_mean_radius(self): + """Get or set a number for the geometrical mean radius of the wire in mm.""" + return self._geometrical_mean_radius + + @geometrical_mean_radius.setter + def geometrical_mean_radius(self, value): + self._geometrical_mean_radius = float_positive(value, 'geometrical_mean_radius') + + @property + def resistance(self): + """Get or set a number for the resistance of the wire in ohms per km of wire. + """ + return self._resistance + + @resistance.setter + def resistance(self, value): + self._resistance = float_positive(value, 'resistance') + + @property + def diameter(self): + """Get or set a number for the diameter of the wire in mm.""" + return self._diameter + + @diameter.setter + def diameter(self, value): + self._diameter = float_positive(value, 'diameter') + + @property + def voltage_level(self): + """Get or set text for the voltage level of the wire. (LV, MV, LV or MV).""" + return self._voltage_level + + @voltage_level.setter + def voltage_level(self, value): + assert value in self.VALID_VOLTAGE_LEVELS, 'Voltage level "{}" is not ' \ + 'acceptable. Choose from:\n{}'.format(value, '\n'.join(self.VALID_PHASES)) + self._voltage_level = value + + @property + def wire_type(self): + """Get or set a text string for the type of wire.""" + return self._wire_type + + @wire_type.setter + def wire_type(self, value): + assert value in self.VALID_WIRE_TYPES, 'Wire type "{}" is not acceptable. ' \ + 'Choose from:\n{}'.format(value, '\n'.join(self.VALID_WIRE_TYPES)) + if value == 'UG concentric neutral': + assert self.concentric_properties is not None, 'Wire concentric_properties' \ + ' must be specified in order to use "UG concentric neutral."' + self._wire_type = value + + @property + def concentric_properties(self): + """Get or set an array of Wire objects for the phases of the wires.""" + return self._concentric_properties + + @concentric_properties.setter + def concentric_properties(self, value): + if value is not None: + assert isinstance(value, ConcentricProperties), \ + 'Expected Wire ConcentricProperties. Got {}.'.format(type(value)) + self._concentric_properties = value + +
    +[docs] + def to_dict(self): + """Get Wire dictionary.""" + base = { + 'type': 'Wire', + 'identifier': self.identifier, + 'ampacity': self.ampacity, + 'geometrical_mean_radius': self.geometrical_mean_radius, + 'resistance': self.resistance, + 'diameter': self.diameter, + 'voltage_level': self.voltage_level, + 'wire_type': self.wire_type + } + if self.concentric_properties is not None: + base['concentric_properties'] = self.concentric_properties.to_dict() + if self._display_name is not None: + base['display_name'] = self._display_name + return base
    + + +
    +[docs] + def to_electrical_database_dict(self): + """Get Wire as it should appear in the URBANopt electrical database.json.""" + base = { + 'nameclass': self.identifier, + 'ampacity (A)': self.ampacity, + 'gmr (mm)': self.geometrical_mean_radius, + 'resistance (ohm/km)': self.resistance, + 'diameter (mm)': self.diameter, + 'voltage level': self.voltage_level, + 'type': self.wire_type + } + if self.concentric_properties is not None: + c_prop = self.concentric_properties + base['gmr neutral (mm)'] = c_prop.geometrical_mean_radius + base['resistance neutral (ohm/km)'] = c_prop.resistance + base['concentric diameter neutral strand (mm)'] = \ + c_prop.concentric_strand_diameter + base['concentric neutral outside diameter (mm)'] = \ + c_prop.concentric_outside_diameter + base['# concentric neutral strands'] = c_prop.strand_count + return base
    + + +
    +[docs] + def lock(self): + """The lock() method will also lock the concentric_properties.""" + self._locked = True + if self.concentric_properties is not None: + self.concentric_properties.lock()
    + + +
    +[docs] + def unlock(self): + """The unlock() method will also unlock the concentric_properties.""" + self._locked = False + if self.concentric_properties is not None: + self.concentric_properties.unlock()
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + new_obj = Wire( + self.identifier, self.ampacity, self.geometrical_mean_radius, + self.resistance, self.diameter, self.voltage_level, self.wire_type) + new_obj._display_name = self._display_name + return new_obj + + def __key(self): + """A tuple based on the object properties, useful for hashing.""" + return ( + self.identifier, self.ampacity, self.geometrical_mean_radius, + self.resistance, self.diameter, self.voltage_level, self.wire_type) + + def __hash__(self): + return hash(self.__key()) + + def __eq__(self, other): + return isinstance(other, Wire) and self.__key() == other.__key() + + def __ne__(self, other): + return not self.__eq__(other) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent wire.""" + return 'Wire: {}'.format(self.identifier)
    + + + +
    +[docs] +@lockable +class ConcentricProperties(object): + """Represents the concentric neutral properties of a wire in OpenDSS. + + Args: + geometrical_mean_radius: A number for the geometric mean of distances between + the neutral strands in millimeters. (Default: 0.8). + resistance: A number for the electrical resistance of the neutral strands in + ohms per kilometer of wire. (Default: 5.8). + concentric_strand_diameter: A number for the diameter of the neutral strand + in millimeters. (Default: 2). + concentric_outside_diameter:A number for the outside diameter of the neutral + strand in millimeters. (Default: 45). + strand_count: A positive integer for the number of concentric neutral + strands. (Default: 24) + + Properties: + * geometrical_mean_radius + * resistance + * concentric_strand_diameter + * concentric_outside_diameter + * strand_count + """ + __slots__ = ( + '_locked', '_geometrical_mean_radius', '_resistance', + '_concentric_strand_diameter', '_concentric_outside_diameter', '_strand_count' + ) + + def __init__( + self, geometrical_mean_radius=0.8, resistance=5.8, + concentric_strand_diameter=2, concentric_outside_diameter=45, + strand_count=24): + """Initialize ConcentricProperties""" + self._locked = False # unlocked by default + self.geometrical_mean_radius = geometrical_mean_radius + self.resistance = resistance + self.concentric_strand_diameter = concentric_strand_diameter + self.concentric_outside_diameter = concentric_outside_diameter + self.strand_count = strand_count + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Create a ConcentricProperties object from a dictionary. + + Args: + data: A dictionary representation of a ConcentricProperties object + in the format below. + + .. code-block:: python + + { + 'type': 'ConcentricProperties', + 'geometrical_mean_radius': 0.8, # gmr in mm + 'resistance': 5.8, # resistance of the wire in ohms/km + 'concentric_strand_diameter': 2, # diameter of the wire in mm + 'concentric_outside_diameter': 45, # outside diameter of the wire in mm + 'strand_count': 24 # integer for the number of strands + } + """ + gmr = data['geometrical_mean_radius'] if 'geometrical_mean_radius' in data \ + else 0.8 + res = data['resistance'] if 'resistance' in data else 5.8 + s_dim = data['concentric_strand_diameter'] if 'concentric_strand_diameter' \ + in data else 2 + o_dim = data['concentric_outside_diameter'] if 'concentric_outside_diameter' \ + in data else 45 + sc = data['strand_count'] if 'strand_count' in data else 24 + return cls(gmr, res, s_dim, o_dim, sc)
    + + + @property + def geometrical_mean_radius(self): + """Get or set a number for the geometrical mean radius of the strands in mm.""" + return self._geometrical_mean_radius + + @geometrical_mean_radius.setter + def geometrical_mean_radius(self, value): + self._geometrical_mean_radius = float_positive(value, 'geometrical_mean_radius') + + @property + def resistance(self): + """Get or set a number for the resistance of the strands in ohms per km of wire. + """ + return self._resistance + + @resistance.setter + def resistance(self, value): + self._resistance = float_positive(value, 'resistance') + + @property + def concentric_strand_diameter(self): + """Get or set a number for the diameter of the neutral strand in mm.""" + return self._concentric_strand_diameter + + @concentric_strand_diameter.setter + def concentric_strand_diameter(self, value): + self._concentric_strand_diameter = \ + float_positive(value, 'concentric_strand_diameter') + + @property + def concentric_outside_diameter(self): + """Get or set a number for the outside diameter of the neutral strand in mm.""" + return self._concentric_outside_diameter + + @concentric_outside_diameter.setter + def concentric_outside_diameter(self, value): + self._concentric_outside_diameter = \ + float_positive(value, 'concentric_outside_diameter') + + @property + def strand_count(self): + """Get or set a positive integer for the number of concentric neutral strands. + """ + return self._strand_count + + @strand_count.setter + def strand_count(self, value): + self._strand_count = int_positive(value, 'strand_count') + +
    +[docs] + def to_dict(self): + """Get ConcentricProperties dictionary.""" + return { + 'type': 'ConcentricProperties', + 'geometrical_mean_radius': self.geometrical_mean_radius, + 'resistance': self.resistance, + 'concentric_strand_diameter': self.concentric_strand_diameter, + 'concentric_outside_diameter': self.concentric_outside_diameter, + 'strand_count': self.strand_count + }
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + new_obj = ConcentricProperties( + self.geometrical_mean_radius, self.resistance, + self.concentric_strand_diameter, self.concentric_outside_diameter, + self.strand_count) + return new_obj + + def __key(self): + """A tuple based on the object properties, useful for hashing.""" + return ( + self.geometrical_mean_radius, self.resistance, + self.concentric_strand_diameter, self.concentric_outside_diameter, + self.strand_count) + + def __hash__(self): + return hash(self.__key()) + + def __eq__(self, other): + return isinstance(other, Wire) and self.__key() == other.__key() + + def __ne__(self, other): + return not self.__eq__(other) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString method.""" + return self.__repr__()
    + + + def __repr__(self): + """Represent wire.""" + return 'ConcentricProperties: [{} strands]'.format(self.strand_count)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/properties/building.html b/docs/_modules/dragonfly_energy/properties/building.html new file mode 100644 index 00000000..3454850a --- /dev/null +++ b/docs/_modules/dragonfly_energy/properties/building.html @@ -0,0 +1,1568 @@ + + + + + + + dragonfly_energy.properties.building — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.properties.building

    +# coding=utf-8
    +"""Building Energy Properties."""
    +import os
    +import json
    +
    +from ladybug.header import Header
    +from ladybug.datacollection import HourlyContinuousCollection
    +from ladybug.datatype.power import Power
    +from ladybug.datatype.time import Time
    +
    +from honeybee_energy.config import folders
    +from honeybee_energy.programtype import ProgramType
    +from honeybee_energy.constructionset import ConstructionSet
    +from honeybee_energy.hvac._base import _HVACSystem
    +from honeybee_energy.hvac.idealair import IdealAirSystem
    +from honeybee_energy.hvac import HVAC_TYPES_DICT
    +from honeybee_energy.shw import SHWSystem
    +from honeybee_energy.lib.constructionsets import generic_construction_set, \
    +    construction_set_by_identifier
    +from honeybee_energy.lib.programtypes import building_program_type_by_identifier
    +
    +
    +
    +[docs] +class BuildingEnergyProperties(object): + """Energy Properties for Dragonfly Building. + + Args: + host: A dragonfly_core Building object that hosts these properties. + construction_set: A honeybee ConstructionSet object to specify all + default constructions for the Faces of the Building. If None, the + Building will use the honeybee default construction set, which is not + representative of a particular building code or climate zone. + Default: None. + + Properties: + * host + * construction_set + * des_cooling_load + * des_heating_load + * des_hot_water_load + * has_des_loads + """ + _HVAC_REGISTRY = None + _HVAC_TYPES_DICT = HVAC_TYPES_DICT + _VINTAGE_MAP = { + 'DOE Ref Pre-1980': ('pre_1980', 'DOE_Ref_Pre_1980'), + 'DOE Ref 1980-2004': ('1980_2004', 'DOE_Ref_1980_2004'), + '90.1-2004': ('2004', 'ASHRAE_2004'), + '90.1-2007': ('2007', 'ASHRAE_2007'), + '90.1-2010': ('2010', 'ASHRAE_2010'), + '90.1-2013': ('2013', 'ASHRAE_2013'), + '90.1-2016': ('2016', 'ASHRAE_2016'), + '90.1-2019': ('2019', 'ASHRAE_2019') + } + __slots__ = ( + '_host', '_construction_set', + '_des_cooling_load', '_des_heating_load', '_des_hot_water_load' + ) + + def __init__(self, host, construction_set=None): + """Initialize Building energy properties.""" + self._host = host + self.construction_set = construction_set + self._des_cooling_load = None # can be set later + self._des_heating_load = None # can be set later + self._des_hot_water_load = None # can be set later + + @property + def host(self): + """Get the Building object hosting these properties.""" + return self._host + + @property + def construction_set(self): + """Get or set the Building ConstructionSet object. + + If not set, it will be the Honeybee default generic ConstructionSet. + """ + if self._construction_set is not None: # set by the user + return self._construction_set + else: + return generic_construction_set + + @construction_set.setter + def construction_set(self, value): + if value is not None: + assert isinstance(value, ConstructionSet), \ + 'Expected ConstructionSet. Got {}'.format(type(value)) + value.lock() # lock in case construction set has multiple references + self._construction_set = value + + @property + def des_cooling_load(self): + """Get or set an optional data collection for building cooling loads for a DES. + + Note that any data collection input here must be an HourlyContinuousCollection, + it must be annual, and it must have a data type of Power in Watts. + """ + return self._des_cooling_load + + @des_cooling_load.setter + def des_cooling_load(self, value): + if value is not None: + value = self._check_data_coll(value, 'DES Cooling') + self._des_cooling_load = value + + @property + def des_heating_load(self): + """Get or set an optional data collection for building heating loads for a DES. + + Note that any data collection input here must be an HourlyContinuousCollection, + it must be annual, and it must have a data type of Power in Watts. + """ + return self._des_heating_load + + @des_heating_load.setter + def des_heating_load(self, value): + if value is not None: + value = self._check_data_coll(value, 'DES Heating') + self._des_heating_load = value + + @property + def des_hot_water_load(self): + """Get or set an optional data collection for building hot water loads for a DES. + + Note that any data collection input here must be an HourlyContinuousCollection, + it must be annual, and it must have a data type of Power in Watts. + """ + return self._des_hot_water_load + + @des_hot_water_load.setter + def des_hot_water_load(self, value): + if value is not None: + value = self._check_data_coll(value, 'DES Hot Water') + self._des_hot_water_load = value + + @property + def has_des_loads(self): + """Get a boolean for whether this Building has DES loads assigned to it.""" + return self._des_cooling_load is not None or self._des_heating_load is not None \ + or self._des_hot_water_load is not None + +
    +[docs] + def averaged_program_type(self, identifier=None, timestep_resolution=1): + """Get a ProgramType that is averaged across all of the children Room2Ds. + + The weights used in the averaging process are the floor area weights and they + account for the multipliers on the child Story objects. + + Args: + identifier: A unique ID text string for the new averaged ProgramType. + Must be < 100 characters and not contain any EnergyPlus special + characters. This will be used to identify the object across a model + and in the exported IDF. If None, the resulting ProgramType will + use the identifier of the host Building. (Default: None) + timestep_resolution: An optional integer for the timestep resolution + at which the schedules will be averaged. Any schedule details + smaller than this timestep will be lost in the averaging process. + Default: 1. + """ + # get the default identifier of the ProgramType if None + identifier = identifier if identifier is not None else \ + '{}_Program'.format(self.host.identifier) + + # compute the floor area weights and programs + flr_areas = [] + program_types = [] + for story in self.host.unique_stories: + for room in story.room_2ds: + flr_areas.append(room.floor_area * story.multiplier) + program_types.append(room.properties.energy.program_type) + total_area = sum(flr_areas) + weights = [room_area / total_area for room_area in flr_areas] + + # compute the averaged program + return ProgramType.average( + identifier, program_types, weights, timestep_resolution)
    + + +
    +[docs] + def set_all_room_2d_program_type(self, program_type): + """Set all of the children Room2Ds of this Building to have the same ProgramType. + + Args: + program_type: A ProgramType to assign to all children Room2Ds. + """ + assert isinstance(program_type, ProgramType), 'Expected ProgramType for ' \ + 'Building set_all_room_2d_program_type. Got {}'.format(type(program_type)) + for room_2d in self.host.unique_room_2ds: + room_2d.properties.energy.program_type = program_type
    + + +
    +[docs] + def set_all_program_type_from_building_type(self, building_type): + """Set the children Room2Ds to have a program mix from a building_type. + + Args: + building_type: A text string for the type of building. This must appear + under the BUILDING_TYPES constant of the honeybee_energy.lib.programtypes + module to be successful. + """ + program = building_program_type_by_identifier(building_type) + self.set_all_room_2d_program_type(program)
    + + +
    +[docs] + def set_all_room_2d_hvac(self, hvac, conditioned_only=True): + """Set all children Room2Ds of this Building to have the same HVAC system. + + Args: + hvac: An HVAC system with properties that will be assigned to all + children Room2Ds. + conditioned_only: Boolean to note whether the input hvac should only + be applied to rooms that are already conditioned. If False, the + hvac will be applied to all rooms. (Default: True). + """ + assert isinstance(hvac, _HVACSystem), 'Expected HVACSystem for Building.' \ + 'set_all_room_2d_hvac. Got {}'.format(type(hvac)) + + new_hvac = hvac.duplicate() + new_hvac._identifier = '{}_{}'.format(hvac.identifier, self.host.identifier) + for room_2d in self.host.unique_room_2ds: + if not conditioned_only or room_2d.properties.energy.is_conditioned: + room_2d.properties.energy.hvac = new_hvac
    + + +
    +[docs] + def add_default_ideal_air(self): + """Add a default IdealAirSystem to all children Room2Ds of this Story. + + The identifier of the systems will be derived from the room identifiers. + """ + for room_2d in self.host.unique_room_2ds: + room_2d.properties.energy.add_default_ideal_air()
    + + +
    +[docs] + def set_all_room_2d_shw(self, shw): + """Set all children Room2Ds of this Building to have the same SHW system. + + Args: + shw: A Service Hot Water (SHW) system with properties that will be + assigned to all children Room2Ds. + """ + assert isinstance(shw, SHWSystem), 'Expected SHWSystem for Building.' \ + 'set_all_room_2d_shw. Got {}'.format(type(shw)) + + new_shw = shw.duplicate() + new_shw._identifier = '{}_{}'.format(shw.identifier, self.host.identifier) + for room_2d in self.host.unique_room_2ds: + room_2d.properties.energy.shw = new_shw
    + + +
    +[docs] + def diversify(self, occupancy_stdev=20, lighting_stdev=20, + electric_equip_stdev=20, gas_equip_stdev=20, hot_water_stdev=20, + infiltration_stdev=20, schedule_offset=1, timestep=1): + """Diversify the ProgramTypes assigned to this Building's Room2Ds. + + This method uses a random number generator and gaussian distribution to + generate loads that vary about the original "mean" programs. Note that the + randomly generated values can be set to something predictable by using the + native Python random.seed() method before running this method. + + In addition to diversifying load values, approximately 2/3 of the schedules + in the resulting Room2Ds will be offset from the mean by the input + schedule_offset (1/3 ahead and another 1/3 behind). + + Args: + occupancy_stdev: A number between 0 and 100 for the percent of the + occupancy people_per_area representing one standard deviation + of diversification from the mean. (Default 20 percent). + lighting_stdev: A number between 0 and 100 for the percent of the + lighting watts_per_area representing one standard deviation + of diversification from the mean. (Default 20 percent). + electric_equip_stdev: A number between 0 and 100 for the percent of the + electric equipment watts_per_area representing one standard deviation + of diversification from the mean. (Default 20 percent). + gas_equip_stdev: A number between 0 and 100 for the percent of the + gas equipment watts_per_area representing one standard deviation + of diversification from the mean. (Default 20 percent). + hot_water_stdev: A number between 0 and 100 for the percent of the + service hot water flow_per_area representing one standard deviation + of diversification from the mean. (Default 20 percent). + infiltration_stdev: A number between 0 and 100 for the percent of the + infiltration flow_per_exterior_area representing one standard deviation + of diversification from the mean. (Default 20 percent). + schedule_offset: A positive integer for the number of timesteps at which all + schedules of the resulting programs will be shifted - roughly 1/3 of + the programs ahead and another 1/3 behind. (Default: 1). + timestep: An integer for the number of timesteps per hour at which the + shifting is occurring. This must be a value between 1 and 60, which + is evenly divisible by 60. 1 indicates that each step is an hour + while 60 indicates that each step is a minute. (Default: 1). + """ + # build a dictionary with the unique ProgramTypes and their assigned rooms + program_dict = {} + for room_2d in self.host.unique_room_2ds: + p_type = room_2d.properties.energy.program_type + try: # see if we have already found the program + program_dict[p_type.identifier][1].append(room_2d) + except KeyError: # this is the firs time encountering the program + program_dict[p_type.identifier] = [p_type, [room_2d]] + + # loop through the dictionary and generate + assign diversified programs + for prog_list in program_dict.values(): + prog, rooms = prog_list[0], prog_list[1] + div_programs = prog.diversify( + len(rooms), occupancy_stdev, lighting_stdev, electric_equip_stdev, + gas_equip_stdev, hot_water_stdev, infiltration_stdev, + schedule_offset, timestep) + for room, d_prog in zip(rooms, div_programs): + room.properties.energy.program_type = d_prog
    + + +
    +[docs] + @classmethod + def from_dict(cls, data, host): + """Create BuildingEnergyProperties from a dictionary. + + Note that the dictionary must be a non-abridged version for this + classmethod to work. + + Args: + data: A dictionary representation of BuildingEnergyProperties. + host: A Building object that hosts these properties. + """ + assert data['type'] == 'BuildingEnergyProperties', \ + 'Expected BuildingEnergyProperties. Got {}.'.format(data['type']) + + new_prop = cls(host) + if 'construction_set' in data and data['construction_set'] is not None: + new_prop.construction_set = \ + ConstructionSet.from_dict(data['construction_set']) + if 'des_cooling_load' in data and data['des_cooling_load'] is not None: + new_prop.des_cooling_load = \ + HourlyContinuousCollection.from_dict(data['des_cooling_load']) + if 'des_heating_load' in data and data['des_heating_load'] is not None: + new_prop.des_heating_load = \ + HourlyContinuousCollection.from_dict(data['des_heating_load']) + if 'des_hot_water_load' in data and data['des_hot_water_load'] is not None: + new_prop.des_heating_load = \ + HourlyContinuousCollection.from_dict(data['des_hot_water_load']) + return new_prop
    + + +
    +[docs] + def apply_properties_from_dict(self, abridged_data, construction_sets): + """Apply properties from a BuildingEnergyPropertiesAbridged dictionary. + + Args: + abridged_data: A BuildingEnergyPropertiesAbridged dictionary (typically + coming from a Model). + construction_sets: A dictionary of ConstructionSets with identifiers + of the sets as keys, which will be used to re-assign construction_sets. + """ + if 'construction_set' in abridged_data and \ + abridged_data['construction_set'] is not None: + self.construction_set = construction_sets[abridged_data['construction_set']] + if 'des_cooling_load' in abridged_data and \ + abridged_data['des_cooling_load'] is not None: + self.des_cooling_load = \ + HourlyContinuousCollection.from_dict(abridged_data['des_cooling_load']) + if 'des_heating_load' in abridged_data and \ + abridged_data['des_heating_load'] is not None: + self.des_heating_load = \ + HourlyContinuousCollection.from_dict(abridged_data['des_heating_load']) + if 'des_hot_water_load' in abridged_data and \ + abridged_data['des_hot_water_load'] is not None: + self.des_heating_load = \ + HourlyContinuousCollection.from_dict(abridged_data['des_hot_water_load'])
    + + +
    +[docs] + def apply_properties_from_geojson_dict(self, data): + """Apply properties from a geoJSON dictionary. + + Args: + data: A dictionary representation of a geoJSON feature properties. + Specifically, this should be the "properties" key describing + a Polygon or MultiPolygon object. + """ + # determine the vintage of the building + template = data['template'] if 'template' in data else '90.1-2019' + vintage = self._VINTAGE_MAP[template] + + # assign the construction set based on climate zone + if 'climate_zone' in data: + zone_int = str(data['climate_zone'])[0] + c_set_id = '{}::{}{}::SteelFramed'.format( + vintage[0], 'ClimateZone', zone_int) + try: + self.construction_set = construction_set_by_identifier(c_set_id) + except ValueError: # not a construction set in the library + pass + + # assign the program based on the building type + if 'building_type' in data: + try: + self.set_all_program_type_from_building_type(data['building_type']) + except ValueError: # not a building type in the library + pass + + # assign the HVAC based on the name + if 'system_type' in data: + hvac_instance = self._hvac_from_long_name(data['system_type'], vintage[1]) + if hvac_instance is not None: + self.set_all_room_2d_hvac(hvac_instance, False)
    + + +
    +[docs] + def to_dict(self, abridged=False): + """Return Building energy properties as a dictionary. + + Args: + abridged: Boolean for whether the full dictionary of the Building should + be written (False) or just the identifier of the the individual + properties (True). Default: False. + """ + base = {'energy': {}} + base['energy']['type'] = 'BuildingEnergyProperties' if not \ + abridged else 'BuildingEnergyPropertiesAbridged' + + # write the properties into the dictionary + if self._construction_set is not None: + base['energy']['construction_set'] = \ + self._construction_set.identifier if abridged else \ + self._construction_set.to_dict() + if self._des_cooling_load is not None: + base['energy']['des_cooling_load'] = self._des_cooling_load.to_dict() + if self._des_heating_load is not None: + base['energy']['des_heating_load'] = self._des_heating_load.to_dict() + if self._des_hot_water_load is not None: + base['energy']['des_hot_water_load'] = self._des_hot_water_load.to_dict() + + return base
    + + +
    +[docs] + def to_building_load_csv(self): + """Get a CSV file string of building loads for DES simulation.""" + time_col, cool, heat, water = self._building_loads() + total = cool + heat + header = ( + 'SecondsFromStart', + 'TotalSensibleLoad', + 'TotalCoolingSensibleLoad', + 'TotalHeatingSensibleLoad', + 'TotalWaterHeating' + ) + file_lines = [','.join(header)] + for s, t, c, h, hw in zip(time_col, total, cool, heat, water): + text_vals = [str(v) for v in (s, t, c, h, hw)] + file_lines.append(','.join(text_vals)) + return '\n'.join(file_lines)
    + + +
    +[docs] + def to_building_load_mos(self): + """Get a MOS file string of building loads for DES simulation.""" + time_col, cool, heat, water = self._building_loads() + file_lines = [ + '#1', + '#Exported loads from Dragonfly', + '\n', + '#First column: Seconds in the year (loads are hourly)', + '#Second column: cooling loads in Watts (as negative numbers).', + '#Third column: space heating loads in Watts', + '#Fourth column: water heating loads in Watts', + '\n' + ] + file_lines.append('#Peak space cooling load = {} Watts'.format(cool.min)) + file_lines.append('#Peak space heating load = {} Watts'.format(cool.max)) + file_lines.append('#Peak water heating load = {} Watts'.format(water.max)) + file_lines.append('double tab1({},4)'.format(len(time_col))) + for s, c, h, hw in zip(time_col, cool, heat, water): + text_vals = [str(v) for v in (s, c, h, hw)] + file_lines.append(';'.join(text_vals)) + return '\n'.join(file_lines)
    + + +
    +[docs] + def duplicate(self, new_host=None): + """Get a copy of this object. + + new_host: A new Building object that hosts these properties. + If None, the properties will be duplicated with the same host. + """ + _host = new_host or self._host + new_prop = BuildingEnergyProperties(_host, self._construction_set) + new_prop._des_cooling_load = self._des_cooling_load + new_prop._des_heating_load = self._des_heating_load + new_prop._des_hot_water_load = self._des_hot_water_load + return new_prop
    + + + def _hvac_from_long_name(self, hvac_long_name, vintage='ASHRAE_2013'): + """Get an HVAC class instance from it's long name (as found in a geoJSON).""" + hvac_reg = None + if BuildingEnergyProperties._HVAC_REGISTRY is None: + ext_folder = [f for f in folders.standards_extension_folders + if f.endswith('honeybee_energy_standards')] + if len(ext_folder) == 1: + hvac_reg = os.path.join(ext_folder[0], 'hvac_registry.json') + if os.path.isfile(hvac_reg): + with open(hvac_reg, 'r') as f: + BuildingEnergyProperties._HVAC_REGISTRY = json.load(f) + BuildingEnergyProperties._HVAC_REGISTRY['Ideal Air System'] = \ + 'IdealAirSystem' + hvac_reg = BuildingEnergyProperties._HVAC_REGISTRY + if hvac_reg is not None: + try: + hvac_class = self._HVAC_TYPES_DICT[hvac_reg[hvac_long_name]] + except KeyError: # HVAC type is not in the library + return None + if hvac_class is IdealAirSystem: + return IdealAirSystem('{} {}'.format(self.host.identifier, 'Ideal Air')) + else: # assume it is an HVAC template + hvac_id = '{} {}'.format(self.host.identifier, hvac_reg[hvac_long_name]) + return hvac_class(hvac_id, vintage, hvac_reg[hvac_long_name]) + + def _building_loads(self): + """Get data collections for cooling, heating, and hot water.""" + assert self.has_des_loads, 'Building "{}" has no building loads assigned ' \ + 'to it for DES simulation.'.format(self.host.display_name) + base_col = self._base_load_collection() + a_per = base_col.header.analysis_period + def_vals = [0] * len(base_col) + def_col = HourlyContinuousCollection(Header(Power(), 'W', a_per), def_vals) + cool = self._des_cooling_load if self._des_cooling_load is not None else def_col + heat = self._des_heating_load if self._des_heating_load is not None else def_col + water = self._des_hot_water_load \ + if self._des_hot_water_load is not None else def_col + # negate cooling as DES simulation needs it that way + neg_cool_vals = [] + for val in cool.values: + v = -val if val != 0 else val + neg_cool_vals.append(v) + cool.values = neg_cool_vals + # make a collection for time in seconds + sec_step = int(3600.0 / a_per.timestep) + time_vals = list(range(sec_step, sec_step * (len(base_col) + 1), sec_step)) + time_col = HourlyContinuousCollection(Header(Time(), 'sec', a_per), time_vals) + return time_col, cool, heat, water + + def _base_load_collection(self): + """Get a data collection to serve as the basis for writing DES loads.""" + if self._des_cooling_load is not None: + return self._des_cooling_load + if self._des_heating_load is not None: + return self._des_heating_load + if self._des_heating_load is not None: + return self._des_hot_water_load + + @staticmethod + def _check_data_coll(value, name): + """Check the data type and units of a Data Collection.""" + assert isinstance(value, HourlyContinuousCollection), 'Expected ' \ + 'HourlyContinuousCollection for {}. Got {}'.format(name, type(value)) + assert value.header.analysis_period.is_annual, '{} data analysis period ' \ + 'is not annual. {}'.format(name, value.header.analysis_period) + assert isinstance(value.header.data_type, Power), '{} must be Power in W. ' \ + 'Got {} in {}'.format(name, value.header.data_type.name, value.header.unit) + if value.header.unit != 'W': + value = value.to_unit('W') + return value + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'Building Energy Properties: {}'.format(self.host.identifier)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/properties/context.html b/docs/_modules/dragonfly_energy/properties/context.html new file mode 100644 index 00000000..92435a76 --- /dev/null +++ b/docs/_modules/dragonfly_energy/properties/context.html @@ -0,0 +1,1191 @@ + + + + + + + dragonfly_energy.properties.context — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.properties.context

    +# coding=utf-8
    +"""Context Shade Energy Properties."""
    +from honeybee.shade import Shade
    +from honeybee_energy.construction.shade import ShadeConstruction
    +from honeybee_energy.schedule.ruleset import ScheduleRuleset
    +from honeybee_energy.schedule.fixedinterval import ScheduleFixedInterval
    +from honeybee_energy.properties.shade import ShadeEnergyProperties
    +from honeybee_energy.properties.shademesh import ShadeMeshEnergyProperties
    +
    +from honeybee_energy.lib.constructions import generic_context
    +
    +
    +
    +[docs] +class ContextShadeEnergyProperties(object): + """Energy Properties for Dragonfly ContextShade. + + Args: + host_shade: A dragonfly_core ContextShade object that hosts these properties. + construction: An optional ShadeConstruction object to set the reflectance + and specularity of the ContextShade. The default is a completely + diffuse construction with 0.2 visible and solar reflectance. + transmittance_schedule: An optional schedule to set the transmittance + of the shade, which can vary throughout the day or year. Default + is a completely opaque object. + + Properties: + * host + * construction + * transmittance_schedule + * is_construction_set_by_user + """ + + __slots__ = ('_host', '_construction', '_transmittance_schedule') + + def __init__(self, host_shade, construction=None, transmittance_schedule=None): + """Initialize ContextShade energy properties.""" + self._host = host_shade + self.construction = construction + self.transmittance_schedule = transmittance_schedule + + @property + def host(self): + """Get the Shade object hosting these properties.""" + return self._host + + @property + def construction(self): + """Get or set a ShadeConstruction for the context shade.""" + if self._construction: # set by user + return self._construction + else: + return generic_context + + @construction.setter + def construction(self, value): + if value is not None: + assert isinstance(value, ShadeConstruction), \ + 'Expected ShadeConstruction. Got {}.'.format(type(value)) + value.lock() # lock editing in case construction has multiple references + self._construction = value + + @property + def transmittance_schedule(self): + """Get or set the transmittance schedule of the shade.""" + return self._transmittance_schedule + + @transmittance_schedule.setter + def transmittance_schedule(self, value): + if value is not None: + assert isinstance(value, (ScheduleRuleset, ScheduleFixedInterval)), \ + 'Expected schedule for shade transmittance schedule. ' \ + 'Got {}.'.format(type(value)) + if value.schedule_type_limit is not None: + assert value.schedule_type_limit.unit == 'fraction', 'Transmittance ' \ + 'schedule should be fractional [Dimensionless]. Got a schedule ' \ + 'of unit_type [{}].'.format(value.schedule_type_limit.unit_type) + value.lock() # lock editing in case schedule has multiple references + self._transmittance_schedule = value + + @property + def is_construction_set_by_user(self): + """Boolean noting if construction is user-set.""" + return self._construction is not None + +
    +[docs] + @classmethod + def from_dict(cls, data, host): + """Create ContextShadeEnergyProperties from a dictionary. + + Note that the dictionary must be a non-abridged version for this + classmethod to work. + + Args: + data: A dictionary representation of ContextShadeEnergyProperties. + host: A ContextShade object that hosts these properties. + """ + assert data['type'] == 'ContextShadeEnergyProperties', \ + 'Expected ContextShadeEnergyProperties. Got {}.'.format(data['type']) + + new_prop = cls(host) + if 'construction' in data and data['construction'] is not None: + new_prop.construction = ShadeConstruction.from_dict(data['construction']) + if 'transmittance_schedule' in data and \ + data['transmittance_schedule'] is not None: + sch_dict = data['transmittance_schedule'] + if sch_dict['type'] == 'ScheduleRuleset': + new_prop.transmittance_schedule = \ + ScheduleRuleset.from_dict(data['transmittance_schedule']) + elif sch_dict['type'] == 'ScheduleFixedInterval': + new_prop.transmittance_schedule = \ + ScheduleFixedInterval.from_dict(data['transmittance_schedule']) + else: + raise ValueError( + 'Expected non-abridged Schedule dictionary for ContextShade ' + 'transmittance_schedule. Got {}.'.format(sch_dict['type'])) + return new_prop
    + + +
    +[docs] + def apply_properties_from_dict(self, abridged_data, constructions, schedules): + """Apply properties from a ContextShadeEnergyPropertiesAbridged dictionary. + + Args: + abridged_data: A ContextShadeEnergyPropertiesAbridged dictionary (typically + coming from a Model). + constructions: A dictionary of constructions with constructions identifiers + as keys, which will be used to re-assign constructions. + schedules: A dictionary of schedules with schedule identifiers as keys, + which will be used to re-assign schedules. + """ + if 'construction' in abridged_data and abridged_data['construction'] is not None: + self.construction = constructions[abridged_data['construction']] + if 'transmittance_schedule' in abridged_data and \ + abridged_data['transmittance_schedule'] is not None: + self.transmittance_schedule = \ + schedules[abridged_data['transmittance_schedule']]
    + + +
    +[docs] + def to_dict(self, abridged=False): + """Return energy properties as a dictionary. + + Args: + abridged: Boolean to note whether the full dictionary describing the + object should be returned (False) or just an abridged version (True). + Default: False. + """ + base = {'energy': {}} + base['energy']['type'] = 'ContextShadeEnergyProperties' if not \ + abridged else 'ContextShadeEnergyPropertiesAbridged' + if self._construction is not None: + base['energy']['construction'] = self._construction.identifier if abridged \ + else self._construction.to_dict() + if self.transmittance_schedule is not None: + base['energy']['transmittance_schedule'] = \ + self.transmittance_schedule.identifier if abridged else \ + self.transmittance_schedule.to_dict() + return base
    + + +
    +[docs] + def to_honeybee(self, new_host): + """Get a honeybee version of this object. + + Args: + new_host: A honeybee-core Shade object that will host these properties. + """ + return ShadeEnergyProperties(new_host, self._construction, + self._transmittance_schedule) \ + if isinstance(new_host, Shade) else \ + ShadeMeshEnergyProperties(new_host, self._construction, + self._transmittance_schedule)
    + + +
    +[docs] + def from_honeybee(self, hb_properties): + """Transfer energy attributes from a Honeybee Shade to Dragonfly ContextShade. + + Args: + hb_properties: The ShadeEnergyProperties of the honeybee Shade that is being + translated to a Dragonfly ContextShade. + """ + self._construction = hb_properties._construction + self._transmittance_schedule = hb_properties._transmittance_schedule
    + + +
    +[docs] + def duplicate(self, new_host=None): + """Get a copy of this object. + + new_host: A new ContextShade object that hosts these properties. + If None, the properties will be duplicated with the same host. + """ + _host = new_host or self._host + return ContextShadeEnergyProperties(_host, self._construction, + self._transmittance_schedule)
    + + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'Context Shade Energy Properties: {}'.format(self.host.identifier)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/properties/model.html b/docs/_modules/dragonfly_energy/properties/model.html new file mode 100644 index 00000000..50fcd6b9 --- /dev/null +++ b/docs/_modules/dragonfly_energy/properties/model.html @@ -0,0 +1,1705 @@ + + + + + + + dragonfly_energy.properties.model — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.properties.model

    +# coding=utf-8
    +"""Model Energy Properties."""
    +try:
    +    from itertools import izip as zip  # python 2
    +except ImportError:
    +    pass   # python 3
    +
    +from honeybee.extensionutil import room_extension_dicts
    +from honeybee_energy.construction.windowshade import WindowConstructionShade
    +from honeybee_energy.construction.dynamic import WindowConstructionDynamic
    +from honeybee_energy.construction.air import AirBoundaryConstruction
    +import honeybee_energy.properties.model as hb_model_properties
    +from honeybee_energy.lib.constructions import generic_context
    +from honeybee_energy.lib.constructionsets import generic_construction_set
    +from honeybee.checkdup import check_duplicate_identifiers
    +
    +from dragonfly.extensionutil import model_extension_dicts
    +
    +
    +
    +[docs] +class ModelEnergyProperties(object): + """Energy Properties for Dragonfly Model. + + Args: + host: A dragonfly_core Model object that hosts these properties. + + Properties: + * host + * materials + * constructions + * face_constructions + * shade_constructions + * construction_sets + * global_construction_set + * schedule_type_limits + * schedules + * construction_schedules + * shade_schedules + * program_type_schedules + * hvac_schedules + * misc_room_schedules + * program_types + * hvacs + * shws + """ + + def __init__(self, host): + """Initialize Model energy properties.""" + self._host = host + + @property + def host(self): + """Get the Model object hosting these properties.""" + return self._host + + @property + def materials(self): + """Get a list of all unique materials contained within the model. + + This includes materials across all Room2Ds, Stories, and Building + ConstructionSets but it does NOT include the Honeybee generic default + construction set. + """ + materials = [] + for constr in self.constructions: + try: + materials.extend(constr.materials) + if constr.has_frame: + materials.append(constr.frame) + if isinstance(constr, WindowConstructionShade): + if constr.is_switchable_glazing: + materials.append(constr.switched_glass_material) + if constr.shade_location == 'Between': + materials.append(constr.window_construction.materials[-2]) + except AttributeError: + pass # ShadeConstruction + return list(set(materials)) + + @property + def constructions(self): + """Get a list of all unique constructions in the model. + + This includes materials across all Room2Ds, Stories, and Building + ConstructionSets but it does NOT include the Honeybee generic default + construction set. + """ + bldg_constrs = [] + for cnstr_set in self.construction_sets: + bldg_constrs.extend(cnstr_set.modified_constructions_unique) + all_constrs = bldg_constrs + self.face_constructions + self.shade_constructions + return list(set(all_constrs)) + + @property + def face_constructions(self): + """Get a list of all unique constructions assigned to Faces, Apertures and Doors. + + These objects only exist under the Building.room_3ds property + """ + constructions = [] + for bldg in self.host.buildings: + for face in bldg.room_3d_faces: + self._check_and_add_obj_construction(face, constructions) + for ap in face.apertures: + self._check_and_add_obj_construction(ap, constructions) + for dr in face.doors: + self._check_and_add_obj_construction(dr, constructions) + return list(set(constructions)) + + @property + def shade_constructions(self): + """Get a list of all unique constructions assigned to ContextShades in the model. + + This will also include any Shade objects assigned to the 3D Honeybee Rooms + of any Model Buildings. + """ + constructions = [] + for shade in self.host.context_shades: + self._check_and_add_obj_construction(shade, constructions) + for bldg in self.host.buildings: + for shd in bldg.room_3d_shades: + self._check_and_add_obj_construction(shd, constructions) + return list(set(constructions)) + + @property + def construction_sets(self): + """Get a list of all unique ConstructionSets in the Model. + + Note that this includes ConstructionSets assigned to individual Stories, + Room2Ds and 3D Honeybee Rooms in the Model's Buildings. + """ + construction_sets = [] + for bldg in self.host.buildings: + self._check_and_add_obj_constr_set(bldg, construction_sets) + for story in bldg.unique_stories: + self._check_and_add_obj_constr_set(story, construction_sets) + for room in story.room_2ds: + self._check_and_add_obj_constr_set(room, construction_sets) + for room in bldg.room_3ds: + self._check_and_add_obj_constr_set(room, construction_sets) + return list(set(construction_sets)) # catch equivalent construction sets + + @property + def global_construction_set(self): + """The global energy construction set. + + This is what is used whenever there is no construction_set assigned to a + Room2D, a parent Story, or a parent Building. + """ + return generic_construction_set + + @property + def schedule_type_limits(self): + """Get a list of all unique schedule type limits contained within the model. + + This includes schedules across all ContextShades and Room2Ds. + """ + type_limits = [] + for sched in self.schedules: + t_lim = sched.schedule_type_limit + if t_lim is not None and not self._instance_in_array(t_lim, type_limits): + type_limits.append(t_lim) + return list(set(type_limits)) + + @property + def schedules(self): + """Get a list of all unique schedules in the model. + + This includes schedules across all ProgramTypes and ContextShades. + """ + all_scheds = self.hvac_schedules + self.program_type_schedules + \ + self.misc_room_schedules + self.shade_schedules + self.construction_schedules + return list(set(all_scheds)) + + @property + def construction_schedules(self): + """Get a list of all unique schedules assigned to constructions in the model. + + This includes schedules on al AirBoundaryConstructions, WindowConstructionShade, + and WindowConstructionDynamic. + """ + schedules = [] + for constr in self.constructions: + if isinstance(constr, AirBoundaryConstruction): + self._check_and_add_schedule(constr.air_mixing_schedule, schedules) + elif isinstance(constr, WindowConstructionShade): + if constr.schedule is not None: + self._check_and_add_schedule(constr.schedule, schedules) + elif isinstance(constr, WindowConstructionDynamic): + self._check_and_add_schedule(constr.schedule, schedules) + return list(set(schedules)) + + @property + def shade_schedules(self): + """Get a list of all unique schedules assigned to ContextShades in the model. + """ + schedules = [] + for shade in self.host._context_shades: + self._check_and_add_shade_schedule(shade, schedules) + return list(set(schedules)) + + @property + def program_type_schedules(self): + """A list of all unique schedules assigned to ProgramTypes in the model.""" + schedules = [] + for p_type in self.program_types: + for sched in p_type.schedules: + self._check_and_add_schedule(sched, schedules) + return list(set(schedules)) + + @property + def hvac_schedules(self): + """Get a list of all unique HVAC-assigned schedules in the model.""" + schedules = [] + for hvac in self.hvacs: + for sched in hvac.schedules: + self._check_and_add_schedule(sched, schedules) + return list(set(schedules)) + + @property + def misc_room_schedules(self): + """Get a list of all unique schedules assigned directly to Rooms in the model. + + This includes schedules for process loads and window ventilation control + that are assigned to Room2Ds. It also includes any schedules assigned directly + to 3D Honeybee Rooms of the model (not through the room program). + + Note that this does not include schedules from ProgramTypes assigned to the + rooms. For this, use the program_type_schedules property. + """ + scheds = [] + for bldg in self.host._buildings: + for story in bldg: + for room in story: + window_vent = room.properties.energy._window_vent_control + processes = room.properties.energy._process_loads + if window_vent is not None: + self._check_and_add_schedule(window_vent.schedule, scheds) + if len(processes) != 0: + for process in processes: + self._check_and_add_schedule(process.schedule, scheds) + for room in bldg.room_3ds: + people = room.properties.energy._people + lighting = room.properties.energy._lighting + electric_equipment = room.properties.energy._electric_equipment + gas_equipment = room.properties.energy._gas_equipment + shw = room.properties.energy._service_hot_water + infiltration = room.properties.energy._infiltration + ventilation = room.properties.energy._ventilation + setpoint = room.properties.energy._setpoint + window_vent = room.properties.energy._window_vent_control + processes = room.properties.energy._process_loads + fans = room.properties.energy._fans + if people is not None: + self._check_and_add_schedule(people.occupancy_schedule, scheds) + self._check_and_add_schedule(people.activity_schedule, scheds) + if lighting is not None: + self._check_and_add_schedule(lighting.schedule, scheds) + if electric_equipment is not None: + self._check_and_add_schedule(electric_equipment.schedule, scheds) + if gas_equipment is not None: + self._check_and_add_schedule(gas_equipment.schedule, scheds) + if shw is not None: + self._check_and_add_schedule(shw.schedule, scheds) + if infiltration is not None: + self._check_and_add_schedule(infiltration.schedule, scheds) + if ventilation is not None and ventilation.schedule is not None: + self._check_and_add_schedule(ventilation.schedule, scheds) + if setpoint is not None: + self._check_and_add_schedule(setpoint.heating_schedule, scheds) + self._check_and_add_schedule(setpoint.cooling_schedule, scheds) + if setpoint.humidifying_schedule is not None: + self._check_and_add_schedule( + setpoint.humidifying_schedule, scheds) + self._check_and_add_schedule( + setpoint.dehumidifying_schedule, scheds) + if window_vent is not None: + self._check_and_add_schedule(window_vent.schedule, scheds) + if len(processes) != 0: + for process in processes: + self._check_and_add_schedule(process.schedule, scheds) + if len(fans) != 0: + for fan in fans: + self._check_and_add_schedule(fan.control.schedule, scheds) + return list(set(scheds)) + + @property + def program_types(self): + """Get a list of all unique ProgramTypes in the Model. + + This includes ProgramTypes assigned to both Room2Ds and 3D Honeybee Rooms. + """ + program_types = [] + for bldg in self.host._buildings: + for story in bldg: + for room in story: + if room.properties.energy._program_type is not None: + if not self._instance_in_array( + room.properties.energy._program_type, program_types): + program_types.append(room.properties.energy._program_type) + for room in bldg.room_3ds: + if room.properties.energy._program_type is not None: + if not self._instance_in_array( + room.properties.energy._program_type, program_types): + program_types.append(room.properties.energy._program_type) + return list(set(program_types)) # catch equivalent program types + + @property + def hvacs(self): + """Get a list of all unique HVAC systems in the Model.""" + hvacs = [] + for bldg in self.host._buildings: + for story in bldg: + for room in story: + if room.properties.energy._hvac is not None: + if not self._instance_in_array( + room.properties.energy._hvac, hvacs): + hvacs.append(room.properties.energy._hvac) + for room in bldg.room_3ds: + if room.properties.energy._hvac is not None: + if not self._instance_in_array(room.properties.energy._hvac, hvacs): + hvacs.append(room.properties.energy._hvac) + return hvacs + + @property + def shws(self): + """Get a list of all unique Service Hot Water (SHW) systems in the Model.""" + shws = [] + for bldg in self.host._buildings: + for story in bldg: + for room in story: + if room.properties.energy._shw is not None: + if not self._instance_in_array( + room.properties.energy._shw, shws): + shws.append(room.properties.energy._shw) + for room in bldg.room_3ds: + if room.properties.energy._shw is not None: + if not self._instance_in_array(room.properties.energy._shw, shws): + shws.append(room.properties.energy._shw) + return shws + +
    +[docs] + def check_all(self, raise_exception=True): + """Check all of the aspects of the Model energy properties. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if any errors are found. If False, this method will simply + return a text string with all errors that were found. + + Returns: + A text string with all errors that were found. This string will be empty + of no errors were found. + """ + msgs = [] + # perform checks for key honeybee model schema rules + msgs.append(self.check_duplicate_construction_set_identifiers(False)) + msgs.append(self.check_duplicate_program_type_identifiers(False)) + msgs.append(self.check_duplicate_hvac_identifiers(False)) + msgs.append(self.check_duplicate_shw_identifiers(False)) + # output a final report of errors or raise an exception + full_msgs = [msg for msg in msgs if msg != ''] + full_msg = '\n'.join(full_msgs) + if raise_exception and len(full_msgs) != 0: + raise ValueError(full_msg) + return full_msg
    + + +
    +[docs] + def check_duplicate_construction_set_identifiers( + self, raise_exception=True, detailed=False): + """Check that there are no duplicate ConstructionSet identifiers in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + return check_duplicate_identifiers( + self.construction_sets, raise_exception, 'ConstructionSet', + detailed, '020003', 'Energy', + error_type='Duplicate ConstructionSet Identifier')
    + + +
    +[docs] + def check_duplicate_program_type_identifiers( + self, raise_exception=True, detailed=False): + """Check that there are no duplicate ProgramType identifiers in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + return check_duplicate_identifiers( + self.program_types, raise_exception, 'ProgramType', + detailed, '020006', 'Energy', error_type='Duplicate ProgramType Identifier')
    + + +
    +[docs] + def check_duplicate_hvac_identifiers(self, raise_exception=True, detailed=False): + """Check that there are no duplicate HVAC identifiers in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + return check_duplicate_identifiers( + self.hvacs, raise_exception, 'HVAC', detailed, '020007', 'Energy', + error_type='Duplicate HVAC Identifier')
    + + +
    +[docs] + def check_duplicate_shw_identifiers(self, raise_exception=True, detailed=False): + """Check that there are no duplicate SHW identifiers in the model. + + Args: + raise_exception: Boolean to note whether a ValueError should be raised + if duplicate identifiers are found. (Default: True). + detailed: Boolean for whether the returned object is a detailed list of + dicts with error info or a string with a message. (Default: False). + + Returns: + A string with the message or a list with a dictionary if detailed is True. + """ + return check_duplicate_identifiers( + self.shws, raise_exception, 'SHW', detailed, '020008', 'Energy', + error_type='Duplicate SHW Identifier')
    + + +
    +[docs] + def apply_properties_from_dict(self, data): + """Apply the energy properties of a dictionary to the host Model of this object. + + Args: + data: A dictionary representation of an entire dragonfly-core Model. + Note that this dictionary must have ModelEnergyProperties in order + for this method to successfully apply the energy properties. + """ + assert 'energy' in data['properties'], \ + 'Dictionary possesses no ModelEnergyProperties.' + _, constructions, construction_sets, _, schedules, program_types, hvacs, shws = \ + hb_model_properties.ModelEnergyProperties.load_properties_from_dict(data) + + # collect lists of energy property dictionaries + building_e_dicts, story_e_dicts, room2d_e_dicts, context_e_dicts = \ + model_extension_dicts(data, 'energy', [], [], [], []) + + # apply energy properties to objects using the energy property dictionaries + for bldg, b_dict in zip(self.host.buildings, building_e_dicts): + if b_dict is not None: + bldg.properties.energy.apply_properties_from_dict( + b_dict, construction_sets) + if bldg.has_room_3ds and b_dict is not None and 'room_3ds' in b_dict and \ + b_dict['room_3ds'] is not None: + room_e_dicts, face_e_dicts, shd_e_dicts, ap_e_dicts, dr_e_dicts = \ + room_extension_dicts(b_dict['room_3ds'], 'energy', [], [], [], [], []) + for room, r_dict in zip(bldg.room_3ds, room_e_dicts): + if r_dict is not None: + room.properties.energy.apply_properties_from_dict( + r_dict, construction_sets, program_types, hvacs, shws, + schedules, constructions) + for face, f_dict in zip(bldg.room_3d_faces, face_e_dicts): + if f_dict is not None: + face.properties.energy.apply_properties_from_dict( + f_dict, constructions) + for aperture, a_dict in zip(bldg.room_3d_apertures, ap_e_dicts): + if a_dict is not None: + aperture.properties.energy.apply_properties_from_dict( + a_dict, constructions) + for door, d_dict in zip(bldg.room_3d_doors, dr_e_dicts): + if d_dict is not None: + door.properties.energy.apply_properties_from_dict( + d_dict, constructions) + for shade, s_dict in zip(bldg.room_3d_shades, shd_e_dicts): + if s_dict is not None: + shade.properties.energy.apply_properties_from_dict( + s_dict, constructions, schedules) + for story, s_dict in zip(self.host.stories, story_e_dicts): + if s_dict is not None: + story.properties.energy.apply_properties_from_dict( + s_dict, construction_sets) + for room, r_dict in zip(self.host.room_2ds, room2d_e_dicts): + if r_dict is not None: + room.properties.energy.apply_properties_from_dict( + r_dict, construction_sets, program_types, hvacs, shws, schedules) + for shade, s_dict in zip(self.host.context_shades, context_e_dicts): + if s_dict is not None: + shade.properties.energy.apply_properties_from_dict( + s_dict, constructions, schedules)
    + + +
    +[docs] + def to_dict(self): + """Return Model energy properties as a dictionary.""" + base = {'energy': {'type': 'ModelEnergyProperties'}} + + # add all materials, constructions and construction sets to the dictionary + schs = self._add_constr_type_objs_to_dict(base) + + # add all schedule type limits, schedules, and program types to the dictionary + self._add_sched_type_objs_to_dict(base, schs) + + return base
    + + +
    +[docs] + def to_honeybee(self, new_host): + """Get a honeybee version of this object. + + Args: + new_host: A honeybee-core Model object that will host these properties. + """ + return hb_model_properties.ModelEnergyProperties(new_host)
    + + +
    +[docs] + def duplicate(self, new_host=None): + """Get a copy of this Model. + + Args: + new_host: A new Model object that hosts these properties. + If None, the properties will be duplicated with the same host. + """ + _host = new_host or self._host + return ModelEnergyProperties(_host)
    + + + def _add_constr_type_objs_to_dict(self, base): + """Add materials, constructions and construction sets to a base dictionary. + + Args: + base: A base dictionary for a Dragonfly Model. + """ + # add the global construction set to the dictionary + gs = self.global_construction_set.to_dict(abridged=True, none_for_defaults=False) + gs['type'] = 'GlobalConstructionSet' + del gs['identifier'] + g_constr = self.global_construction_set.constructions_unique + g_materials = [] + for constr in g_constr: + try: + g_materials.extend(constr.materials) + except AttributeError: + pass # ShadeConstruction or AirBoundaryConstruction + gs['context_construction'] = generic_context.identifier + gs['constructions'] = [generic_context.to_dict()] + for cnst in g_constr: + try: + gs['constructions'].append(cnst.to_dict(abridged=True)) + except TypeError: # ShadeConstruction + gs['constructions'].append(cnst.to_dict()) + gs['materials'] = [mat.to_dict() for mat in set(g_materials)] + base['energy']['global_construction_set'] = gs + + # add all ConstructionSets to the dictionary + base['energy']['construction_sets'] = [] + construction_sets = self.construction_sets + for cnstr_set in construction_sets: + base['energy']['construction_sets'].append(cnstr_set.to_dict(abridged=True)) + + # add all unique Constructions to the dictionary + room_constrs = [] + for cnstr_set in construction_sets: + room_constrs.extend(cnstr_set.modified_constructions_unique) + mass_constrs = [] + for bldg in self.host.buildings: + for room in bldg.room_3ds: + for int_mass in room.properties.energy._internal_masses: + constr = int_mass.construction + if not self._instance_in_array(constr, mass_constrs): + mass_constrs.append(constr) + all_constrs = room_constrs + self.face_constructions + self.shade_constructions + constructions = tuple(set(all_constrs)) + base['energy']['constructions'] = [] + for cnst in constructions: + try: + base['energy']['constructions'].append(cnst.to_dict(abridged=True)) + except TypeError: # ShadeConstruction + base['energy']['constructions'].append(cnst.to_dict()) + + # add all unique Materials to the dictionary + materials = [] + for cnstr in constructions: + try: + materials.extend(cnstr.materials) + if cnstr.has_frame: + materials.append(cnstr.frame) + if isinstance(cnstr, WindowConstructionShade): + if cnstr.is_switchable_glazing: + materials.append(cnstr.switched_glass_material) + if cnstr.shade_location == 'Between': + materials.append(cnstr.window_construction.materials[-2]) + except AttributeError: + pass # ShadeConstruction + base['energy']['materials'] = [mat.to_dict() for mat in set(materials)] + + # extract all of the schedules from the constructions + schedules = [] + for constr in constructions: + if isinstance(constr, AirBoundaryConstruction): + self._check_and_add_schedule(constr.air_mixing_schedule, schedules) + elif isinstance(constr, WindowConstructionShade): + if constr.schedule is not None: + self._check_and_add_schedule(constr.schedule, schedules) + elif isinstance(constr, WindowConstructionDynamic): + self._check_and_add_schedule(constr.schedule, schedules) + return schedules + + def _add_sched_type_objs_to_dict(self, base, schs): + """Add schedule type limits, schedules, and program types to a base dictionary. + + Args: + base: A base dictionary for a Dragonfly Model. + schs: A list of additional schedules to be serialized to the + base dictionary. + """ + # add all unique hvacs to the dictionary + hvacs = self.hvacs + base['energy']['hvacs'] = [] + for hvac in hvacs: + base['energy']['hvacs'].append(hvac.to_dict(abridged=True)) + + # add all unique shws to the dictionary + base['energy']['shws'] = [shw.to_dict() for shw in self.shws] + + # add all unique ProgramTypes to the dictionary + program_types = self.program_types + base['energy']['program_types'] = [] + for p_type in program_types: + base['energy']['program_types'].append(p_type.to_dict(abridged=True)) + + # add all unique Schedules to the dictionary + p_type_scheds = [] + for p_type in program_types: + for sched in p_type.schedules: + self._check_and_add_schedule(sched, p_type_scheds) + hvac_scheds = [] + for hvac in hvacs: + for sched in hvac.schedules: + self._check_and_add_schedule(sched, hvac_scheds) + all_scheds = hvac_scheds + p_type_scheds + self.misc_room_schedules + \ + self.shade_schedules + schs + schedules = tuple(set(all_scheds)) + base['energy']['schedules'] = [] + for sched in schedules: + base['energy']['schedules'].append(sched.to_dict(abridged=True)) + + # add all unique ScheduleTypeLimits to the dictionary + type_limits = [] + for sched in schedules: + t_lim = sched.schedule_type_limit + if t_lim is not None and not self._instance_in_array(t_lim, type_limits): + type_limits.append(t_lim) + base['energy']['schedule_type_limits'] = \ + [s_typ.to_dict() for s_typ in set(type_limits)] + + def _check_and_add_obj_constr_set(self, obj, construction_sets): + """Check if a construction set is assigned to an object and add it to a list.""" + c_set = obj.properties.energy._construction_set + if c_set is not None: + if not self._instance_in_array(c_set, construction_sets): + construction_sets.append(c_set) + + def _check_and_add_obj_construction(self, obj, constructions): + """Check if a construction is assigned to an object and add it to a list.""" + constr = obj.properties.energy._construction + if constr is not None: + if not self._instance_in_array(constr, constructions): + constructions.append(constr) + + def _check_and_add_shade_schedule(self, obj, schedules): + """Check if a schedule is assigned to a shade and add it to a list.""" + sched = obj.properties.energy._transmittance_schedule + if sched is not None: + if not self._instance_in_array(sched, schedules): + schedules.append(sched) + + def _check_and_add_schedule(self, sched, schedules): + """Check if a schedule is in a list and add it if not.""" + if not self._instance_in_array(sched, schedules): + schedules.append(sched) + + @staticmethod + def _instance_in_array(object_instance, object_array): + """Check if a specific object instance is already in an array. + + This can be much faster than `if object_instance in object_array` + when you expect to be testing a lot of the same instance of an object for + inclusion in an array since the builtin method uses an == operator to + test inclusion. + """ + for val in object_array: + if val is object_instance: + return True + return False + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'Model Energy Properties: {}'.format(self.host.identifier)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/properties/room2d.html b/docs/_modules/dragonfly_energy/properties/room2d.html new file mode 100644 index 00000000..d685bfb8 --- /dev/null +++ b/docs/_modules/dragonfly_energy/properties/room2d.html @@ -0,0 +1,1451 @@ + + + + + + + dragonfly_energy.properties.room2d — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.properties.room2d

    +# coding=utf-8
    +"""Room2D Energy Properties."""
    +from honeybee.boundarycondition import Outdoors
    +from honeybee_energy.properties.room import RoomEnergyProperties
    +from honeybee_energy.programtype import ProgramType
    +from honeybee_energy.constructionset import ConstructionSet
    +from honeybee_energy.hvac import HVAC_TYPES_DICT
    +from honeybee_energy.hvac._base import _HVACSystem
    +from honeybee_energy.hvac.idealair import IdealAirSystem
    +from honeybee_energy.shw import SHWSystem
    +from honeybee_energy.ventcool.control import VentilationControl
    +from honeybee_energy.ventcool.opening import VentilationOpening
    +from honeybee_energy.load.process import Process
    +
    +from honeybee_energy.lib.constructionsets import generic_construction_set
    +from honeybee_energy.lib.programtypes import plenum_program
    +
    +
    +
    +[docs] +class Room2DEnergyProperties(object): + """Energy Properties for Dragonfly Room2D. + + Args: + host: A dragonfly_core Room2D object that hosts these properties. + program_type: A honeybee ProgramType object to specify all default + schedules and loads for the Room2D. If None, the Room2D will have a + Plenum program (with no loads or setpoints). Default: None. + construction_set: A honeybee ConstructionSet object to specify all + default constructions for the Faces of the Room2D. If None, the + Room2D will use the honeybee default construction set, which is not + representative of a particular building code or climate zone. + Default: None. + hvac: A honeybee HVAC object (such as an IdealAirSystem) that specifies + how the Room2D is conditioned. If None, it will be assumed that the + Room2D is not conditioned. Default: None. + + Properties: + * host + * program_type + * construction_set + * hvac + * shw + * window_vent_control + * window_vent_opening + * process_loads + * total_process_load + * is_conditioned + * has_window_opening + """ + + __slots__ = ('_host', '_program_type', '_construction_set', '_hvac', '_shw', + '_window_vent_control', '_window_vent_opening', '_process_loads') + + def __init__( + self, host, program_type=None, construction_set=None, hvac=None, shw=None): + """Initialize Room2D energy properties.""" + self._host = host + self.program_type = program_type + self.construction_set = construction_set + self.hvac = hvac + self.shw = shw + self._window_vent_control = None # set to None by default + self._window_vent_opening = None # set to None by default + self._process_loads = [] + + @property + def host(self): + """Get the Room2D object hosting these properties.""" + return self._host + + @property + def program_type(self): + """Get or set the ProgramType object for the Room2D. + + If not set, it will default to a plenum ProgramType (with no loads assigned). + """ + if self._program_type is not None: # set by the user + return self._program_type + else: + return plenum_program + + @program_type.setter + def program_type(self, value): + if value is not None: + assert isinstance(value, ProgramType), 'Expected ProgramType for Room2D ' \ + 'program_type. Got {}'.format(type(value)) + value.lock() # lock in case program type has multiple references + self._program_type = value + + @property + def construction_set(self): + """Get or set the Room2D ConstructionSet object. + + If not set, it will be set by the parent Story or will be the Honeybee + default generic ConstructionSet. + """ + if self._construction_set is not None: # set by the user + return self._construction_set + elif self._host.has_parent: # set by parent story + return self._host.parent.properties.energy.construction_set + else: + return generic_construction_set + + @construction_set.setter + def construction_set(self, value): + if value is not None: + assert isinstance(value, ConstructionSet), \ + 'Expected ConstructionSet. Got {}'.format(type(value)) + value.lock() # lock in case construction set has multiple references + self._construction_set = value + + @property + def hvac(self): + """Get or set the HVAC object for the Room2D. + + If None, it will be assumed that the Room2D is not conditioned. + """ + return self._hvac + + @hvac.setter + def hvac(self, value): + if value is not None: + assert isinstance(value, _HVACSystem), \ + 'Expected HVACSystem for Room2D hvac. Got {}'.format(type(value)) + value.lock() # lock in case hvac has multiple references + self._hvac = value + + @property + def shw(self): + """Get or set the SHWSystem object for the Room2D. + + If None, all hot water loads will be met with a system that doesn't compute + fuel or electricity usage. + """ + return self._shw + + @shw.setter + def shw(self, value): + if value is not None: + assert isinstance(value, SHWSystem), \ + 'Expected SHWSystem for Room shw. Got {}'.format(type(value)) + value.lock() # lock in case shw has multiple references + self._shw = value + + @property + def window_vent_control(self): + """Get or set a VentilationControl object to dictate the opening of windows. + + If None or no window_vent_opening object is assigned to this Room2D, + the windows will never open. + """ + return self._window_vent_control + + @window_vent_control.setter + def window_vent_control(self, value): + if value is not None: + assert isinstance(value, VentilationControl), 'Expected VentilationControl' \ + ' object for Room2D window_vent_control. Got {}'.format(type(value)) + value.lock() # lock because we don't duplicate the object + self._window_vent_control = value + + @property + def window_vent_opening(self): + """Get or set a VentilationOpening object for the operability of all windows. + + If None or no window_vent_control object is assigned to this Room2D, + the windows will never open. + """ + return self._window_vent_opening + + @window_vent_opening.setter + def window_vent_opening(self, value): + if value is not None: + assert isinstance(value, VentilationOpening), 'Expected VentilationOpening' \ + ' for Room2D window_vent_opening. Got {}'.format(type(value)) + self._window_vent_opening = value + + @property + def process_loads(self): + """Get or set an array of Process objects for process loads within the Room2D.""" + return tuple(self._process_loads) + + @process_loads.setter + def process_loads(self, value): + for val in value: + assert isinstance(val, Process), 'Expected Process ' \ + 'object for Room process_loads. Got {}'.format(type(val)) + val.lock() # lock because we don't duplicate the object + self._process_loads = list(value) + + @property + def total_process_load(self): + """Get a number for the total process load in W within the room.""" + return sum([load.watts for load in self._process_loads]) + + @property + def is_conditioned(self): + """Boolean to note whether the Room is conditioned.""" + return self._hvac is not None + + @property + def has_window_opening(self): + """Boolean to note whether the Room has operable windows with controls.""" + return self._window_vent_opening is not None + +
    +[docs] + def add_default_ideal_air(self): + """Add a default IdealAirSystem to this Room2D. + + The identifier of this system will be derived from the room identifier + and will align with the naming convention that EnergyPlus uses for + templates Ideal Air systems. + """ + hvac_id = '{} Ideal Loads Air System'.format(self.host.identifier) + self.hvac = IdealAirSystem(hvac_id)
    + + +
    +[docs] + def add_process_load(self, process_load): + """Add a Process load to this Room2D. + + Args: + process_load: A Process load to add to this Room. + """ + assert isinstance(process_load, Process), \ + 'Expected Process load object. Got {}.'.format(type(process_load)) + process_load.lock() # lock because we don't duplicate the object + self._process_loads.append(process_load)
    + + +
    +[docs] + def remove_process_loads(self): + """Remove all Process loads from the Room.""" + self._process_loads = []
    + + +
    +[docs] + @classmethod + def from_dict(cls, data, host): + """Create Room2DEnergyProperties from a dictionary. + + Note that the dictionary must be a non-abridged version for this + classmethod to work. + + Args: + data: A dictionary representation of Room2DEnergyProperties in the + format below. + host: A Room2D object that hosts these properties. + + .. code-block:: python + + { + "type": 'Room2DEnergyProperties', + "construction_set": {}, # A ConstructionSet dictionary + "program_type": {}, # A ProgramType dictionary + "hvac": {}, # A HVACSystem dictionary + "shw": {}, # A SHWSystem dictionary + "daylighting_control": {}, # A DaylightingControl dictionary + "window_vent_control": {} # A VentilationControl dictionary + "process_loads": [] # An array of Process dictionaries + } + """ + assert data['type'] == 'Room2DEnergyProperties', \ + 'Expected Room2DEnergyProperties. Got {}.'.format(data['type']) + + new_prop = cls(host) + if 'construction_set' in data and data['construction_set'] is not None: + new_prop.construction_set = \ + ConstructionSet.from_dict(data['construction_set']) + if 'program_type' in data and data['program_type'] is not None: + new_prop.program_type = ProgramType.from_dict(data['program_type']) + if 'hvac' in data and data['hvac'] is not None: + hvac_class = HVAC_TYPES_DICT[data['hvac']['type']] + new_prop.hvac = hvac_class.from_dict(data['hvac']) + if 'shw' in data and data['shw'] is not None: + new_prop.shw = SHWSystem.from_dict(data['shw']) + cls._deserialize_window_vent(new_prop, data, {}) + if 'process_loads' in data and data['process_loads'] is not None: + new_prop.process_loads = \ + [Process.from_dict(dat) for dat in data['process_loads']] + return new_prop
    + + +
    +[docs] + def apply_properties_from_dict(self, abridged_data, construction_sets, + program_types, hvacs, shws, schedules): + """Apply properties from a Room2DEnergyPropertiesAbridged dictionary. + + Args: + abridged_data: A Room2DEnergyPropertiesAbridged dictionary (typically + coming from a Model). + construction_sets: A dictionary of ConstructionSets with identifiers + of the sets as keys, which will be used to re-assign construction_sets. + program_types: A dictionary of ProgramTypes with identifiers of the + types ask keys, which will be used to re-assign program_types. + hvacs: A dictionary of HVACSystems with the identifiers of the + systems as keys, which will be used to re-assign hvac to the Room. + shws: A dictionary of SHWSystems with the identifiers of the systems as + keys, which will be used to re-assign shw to the Room. + schedules: A dictionary of Schedules with identifiers of the schedules as + keys, which will be used to re-assign schedules. + """ + if 'construction_set' in abridged_data and \ + abridged_data['construction_set'] is not None: + self.construction_set = construction_sets[abridged_data['construction_set']] + if 'program_type' in abridged_data and abridged_data['program_type'] is not None: + self.program_type = program_types[abridged_data['program_type']] + if 'hvac' in abridged_data and abridged_data['hvac'] is not None: + self.hvac = hvacs[abridged_data['hvac']] + if 'shw' in abridged_data and abridged_data['shw'] is not None: + self.shw = shws[abridged_data['shw']] + self._deserialize_window_vent(self, abridged_data, schedules) + if 'process_loads' in abridged_data and \ + abridged_data['process_loads'] is not None: + for dat in abridged_data['process_loads']: + if dat['type'] == 'Process': + self._process_loads.append(Process.from_dict(dat)) + else: + self._process_loads.append( + Process.from_dict_abridged(dat, schedules) + )
    + + +
    +[docs] + def to_dict(self, abridged=False): + """Return Room2D energy properties as a dictionary. + + Args: + abridged: Boolean for whether the full dictionary of the Room2D should + be written (False) or just the identifier of the the individual + properties (True). Default: False. + """ + base = {'energy': {}} + base['energy']['type'] = 'Room2DEnergyProperties' if not \ + abridged else 'Room2DEnergyPropertiesAbridged' + + # write the ProgramType into the dictionary + if self._program_type is not None: + base['energy']['program_type'] = self._program_type.identifier if abridged \ + else self._program_type.to_dict() + + # write the ConstructionSet into the dictionary + if self._construction_set is not None: + base['energy']['construction_set'] = \ + self._construction_set.identifier if abridged else \ + self._construction_set.to_dict() + + # write the hvac into the dictionary + if self._hvac is not None: + base['energy']['hvac'] = \ + self._hvac.identifier if abridged else self._hvac.to_dict() + + # write the shw into the dictionary + if self._shw is not None: + base['energy']['shw'] = \ + self._shw.identifier if abridged else self._shw.to_dict() + + # write the window_vent_control and window_vent_opening into the dictionary + if self._window_vent_control is not None: + base['energy']['window_vent_control'] = \ + self.window_vent_control.to_dict(abridged) + if self._window_vent_opening is not None: + base['energy']['window_vent_opening'] = self.window_vent_opening.to_dict() + + # write the process_loads into the dictionary + if len(self._process_loads) != 0: + base['energy']['process_loads'] = \ + [p.to_dict(abridged) for p in self._process_loads] + + return base
    + + +
    +[docs] + def to_honeybee(self, new_host): + """Get a honeybee version of this object. + + Args: + new_host: A honeybee-core Room object that will host these properties. + """ + constr_set = self.construction_set # includes story and building-assigned sets + hb_constr = constr_set if constr_set is not generic_construction_set else None + hb_prop = RoomEnergyProperties( + new_host, self._program_type, hb_constr, self._hvac, self._shw) + if self._window_vent_control is not None: + hb_prop.window_vent_control = self.window_vent_control + if self._window_vent_opening is not None: + for face in new_host.faces: # set all apertures to be operable + for ap in face.apertures: + if isinstance(ap.boundary_condition, Outdoors): + ap.is_operable = True + hb_prop.assign_ventilation_opening(self.window_vent_opening) + if len(self._process_loads) != 0: + hb_prop.process_loads = self.process_loads + return hb_prop
    + + +
    +[docs] + def from_honeybee(self, hb_properties): + """Transfer energy attributes from a Honeybee Room to Dragonfly Room2D. + + Args: + hb_properties: The RoomEnergyProperties of the honeybee Room that is being + translated to a Dragonfly Room2D. + """ + self._program_type = hb_properties._program_type + self._construction_set = hb_properties._construction_set + self._hvac = hb_properties._hvac + self._shw = hb_properties._shw + self._process_loads = hb_properties._process_loads[:] # copy the list + if hb_properties._window_vent_control is not None: + self._window_vent_control = hb_properties._window_vent_control + for face in hb_properties.host.faces: + for ap in face.apertures: + if ap.properties.energy.vent_opening is not None: + self._window_vent_opening = ap.properties.energy.vent_opening + break + if self._window_vent_opening is not None: + break
    + + +
    +[docs] + def duplicate(self, new_host=None): + """Get a copy of this object. + + Args: + new_host: A new Room2D object that hosts these properties. + If None, the properties will be duplicated with the same host. + """ + _host = new_host or self._host + hb_prop = Room2DEnergyProperties( + _host, self._program_type, self._construction_set, self._hvac, self._shw) + hb_prop._window_vent_control = self._window_vent_control + hb_prop._window_vent_opening = self._window_vent_opening + hb_prop._process_loads = self._process_loads[:] # copy process load list + return hb_prop
    + + + @staticmethod + def _deserialize_window_vent(new_prop, data, schedules): + """Re-serialize window ventilation objects from a dict and apply to new_prop. + + Args: + new_prop: A Room2DEnergyProperties to apply the window ventilation to. + data: A dictionary representation of Room2DEnergyProperties. + """ + if 'window_vent_control' in data and data['window_vent_control'] is not None: + wvc = data['window_vent_control'] + new_prop.window_vent_control = \ + VentilationControl.from_dict_abridged(wvc, schedules) \ + if wvc['type'] == 'VentilationControlAbridged' else \ + VentilationControl.from_dict(wvc) + if 'window_vent_opening' in data and data['window_vent_opening'] is not None: + new_prop.window_vent_opening = \ + VentilationOpening.from_dict(data['window_vent_opening']) + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'Room2D Energy Properties: {}'.format(self.host.identifier)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/properties/story.html b/docs/_modules/dragonfly_energy/properties/story.html new file mode 100644 index 00000000..05d3a242 --- /dev/null +++ b/docs/_modules/dragonfly_energy/properties/story.html @@ -0,0 +1,1222 @@ + + + + + + + dragonfly_energy.properties.story — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.properties.story

    +# coding=utf-8
    +"""Story Energy Properties."""
    +from honeybee_energy.programtype import ProgramType
    +from honeybee_energy.constructionset import ConstructionSet
    +from honeybee_energy.hvac._base import _HVACSystem
    +from honeybee_energy.shw import SHWSystem
    +
    +from honeybee_energy.lib.constructionsets import generic_construction_set
    +
    +
    +
    +[docs] +class StoryEnergyProperties(object): + """Energy Properties for Dragonfly Story. + + Args: + host: A dragonfly_core Story object that hosts these properties. + construction_set: A honeybee ConstructionSet object to specify all + default constructions for the Faces of the Story. If None, the + Story will use the honeybee default construction set, which is not + representative of a particular building code or climate zone. + Default: None. + + Properties: + * host + * construction_set + """ + + __slots__ = ('_host', '_construction_set') + + def __init__(self, host, construction_set=None): + """Initialize Story energy properties.""" + self._host = host + self.construction_set = construction_set + + @property + def host(self): + """Get the Story object hosting these properties.""" + return self._host + + @property + def construction_set(self): + """Get or set the Story ConstructionSet object. + + If not set, it will be set by the parent Building or will be the Honeybee + default generic ConstructionSet. + """ + if self._construction_set is not None: # set by the user + return self._construction_set + elif self._host.has_parent: # set by parent building + return self._host.parent.properties.energy.construction_set + else: + return generic_construction_set + + @construction_set.setter + def construction_set(self, value): + if value is not None: + assert isinstance(value, ConstructionSet), \ + 'Expected ConstructionSet. Got {}'.format(type(value)) + value.lock() # lock in case construction set has multiple references + self._construction_set = value + +
    +[docs] + def averaged_program_type(self, identifier=None, timestep_resolution=1): + """Get a ProgramType that is averaged across all of the children Room2Ds. + + The weights used in the averaging process are the floor area weights. + + Args: + identifier: A unique ID text string for the new averaged ProgramType. + Must be < 100 characters and not contain any EnergyPlus special + characters. This will be used to identify the object across a model + and in the exported IDF. If None, the resulting ProgramType will + use the identifier of the host Building. (Default: None) + timestep_resolution: An optional integer for the timestep resolution + at which the schedules will be averaged. Any schedule details + smaller than this timestep will be lost in the averaging process. + Default: 1. + """ + # get the default identifier of the ProgramType if None + identifier = identifier if identifier is not None else \ + '{}_Program'.format(self.host.identifier) + + # compute the floor area weights + flr_areas = [room.floor_area for room in self.host.room_2ds] + total_area = sum(flr_areas) + weights = [room_area / total_area for room_area in flr_areas] + + # compute the averaged program + program_types = [room.properties.energy.program_type + for room in self.host.room_2ds] + return ProgramType.average( + identifier, program_types, weights, timestep_resolution)
    + + +
    +[docs] + def set_all_room_2d_program_type(self, program_type): + """Set all of the children Room2Ds of this Story to have the same ProgramType. + + Args: + program_type: A ProgramType to assign to all children Room2Ds. + """ + assert isinstance(program_type, ProgramType), 'Expected ProgramType for Story ' \ + 'set_all_room_2d_program_type. Got {}'.format(type(program_type)) + for room_2d in self.host.room_2ds: + room_2d.properties.energy.program_type = program_type
    + + +
    +[docs] + def set_all_room_2d_hvac(self, hvac, conditioned_only=True): + """Set all children Room2Ds of this Story to have the same HVAC system. + + Args: + hvac: An HVAC system with properties that will be assigned to all + children Room2Ds. + conditioned_only: Boolean to note whether the input hvac should only + be applied to rooms that are already conditioned. If False, the + hvac will be applied to all rooms. (Default: True). + """ + assert isinstance(hvac, _HVACSystem), 'Expected HVACSystem for Story.' \ + 'set_all_room_2d_hvac. Got {}'.format(type(hvac)) + + new_hvac = hvac.duplicate() + new_hvac._identifier = '{}_{}'.format(hvac.identifier, self.host.identifier) + for room_2d in self.host.room_2ds: + if not conditioned_only or room_2d.properties.energy.is_conditioned: + room_2d.properties.energy.hvac = new_hvac
    + + +
    +[docs] + def add_default_ideal_air(self): + """Add a default IdealAirSystem to all children Room2Ds of this Story. + + The identifier of the systems will be derived from the room identifiers. + """ + for room_2d in self.host.room_2ds: + room_2d.properties.energy.add_default_ideal_air()
    + + +
    +[docs] + def set_all_room_2d_shw(self, shw): + """Set all children Room2Ds of this Story to have the same HVAC system. + + Args: + shw: An HVAC system with properties that will be assigned to all + children Room2Ds. + """ + assert isinstance(shw, SHWSystem), 'Expected SHWSystem for Story.' \ + 'set_all_room_2d_shw. Got {}'.format(type(shw)) + + new_shw = shw.duplicate() + new_shw._identifier = '{}_{}'.format(shw.identifier, self.host.identifier) + for room_2d in self.host.room_2ds: + room_2d.properties.energy.shw = new_shw
    + + +
    +[docs] + @classmethod + def from_dict(cls, data, host): + """Create StoryEnergyProperties from a dictionary. + + Note that the dictionary must be a non-abridged version for this + classmethod to work. + + Args: + data: A dictionary representation of StoryEnergyProperties. + host: A Story object that hosts these properties. + """ + assert data['type'] == 'StoryEnergyProperties', \ + 'Expected StoryEnergyProperties. Got {}.'.format(data['type']) + + new_prop = cls(host) + if 'construction_set' in data and data['construction_set'] is not None: + new_prop.construction_set = \ + ConstructionSet.from_dict(data['construction_set']) + + return new_prop
    + + +
    +[docs] + def apply_properties_from_dict(self, abridged_data, construction_sets): + """Apply properties from a StoryEnergyPropertiesAbridged dictionary. + + Args: + abridged_data: A StoryEnergyPropertiesAbridged dictionary (typically + coming from a Model). + construction_sets: A dictionary of ConstructionSets with identifiers + of the sets as keys, which will be used to re-assign construction_sets. + """ + if 'construction_set' in abridged_data and \ + abridged_data['construction_set'] is not None: + self.construction_set = construction_sets[abridged_data['construction_set']]
    + + +
    +[docs] + def to_dict(self, abridged=False): + """Return Story energy properties as a dictionary. + + Args: + abridged: Boolean for whether the full dictionary of the Story should + be written (False) or just the identifier of the the individual + properties (True). Default: False. + """ + base = {'energy': {}} + base['energy']['type'] = 'StoryEnergyProperties' if not \ + abridged else 'StoryEnergyPropertiesAbridged' + + # write the ConstructionSet into the dictionary + if self._construction_set is not None: + base['energy']['construction_set'] = \ + self._construction_set.identifier if abridged else \ + self._construction_set.to_dict() + + return base
    + + +
    +[docs] + def duplicate(self, new_host=None): + """Get a copy of this object. + + new_host: A new Story object that hosts these properties. + If None, the properties will be duplicated with the same host. + """ + _host = new_host or self._host + return StoryEnergyProperties(_host, self._construction_set)
    + + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'Story Energy Properties: {}'.format(self.host.identifier)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/reopt.html b/docs/_modules/dragonfly_energy/reopt.html new file mode 100644 index 00000000..75389a12 --- /dev/null +++ b/docs/_modules/dragonfly_energy/reopt.html @@ -0,0 +1,1691 @@ + + + + + + + dragonfly_energy.reopt — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.reopt

    +# coding=utf-8
    +"""Complete set of REopt Simulation Settings."""
    +from __future__ import division
    +
    +import os
    +import json
    +import math
    +
    +from ladybug_geometry.geometry2d.pointvector import Point2D, Vector2D
    +from ladybug_geometry.geometry2d.polygon import Polygon2D
    +from honeybee.typing import float_positive, float_in_range, int_positive, \
    +    valid_ep_string, valid_string
    +from dragonfly.projection import polygon_to_lon_lat, meters_to_long_lat_factors, \
    +    origin_long_lat_from_location
    +
    +
    +
    +[docs] +class REoptParameter(object): + """Complete set of REopt Simulation Settings. + + Args: + financial_parameter: A FinancialParameter object to describe the parameters + of the financial analysis. If None, a set of defaults will be + generated. (Default: None). + wind_parameter: A WindParameter object to set the cost and max amount of + wind to include in the analysis. If None, no wind will be included + in the analysis. (Default: None). + pv_parameter: A PVParameter object to set the cost and max amount of + photovoltaic to include in the analysis. If None, no PV will be included + in the analysis. (Default: None). + storage_parameter: A StorageParameter object to set the cost and max amount of + electricity storage to include in the analysis. If None, no storage + will be included in the analysis. (Default: None). + generator_parameter: A GeneratorParameter object to set the cost and max amount + of generators to include in the analysis. If None, no generators + will be included in the analysis. (Default: None). + + Properties: + * financial_parameter + * wind_parameter + * pv_parameter + * storage_parameter + * generator_parameter + """ + def __init__(self, financial_parameter=None, wind_parameter=None, pv_parameter=None, + storage_parameter=None, generator_parameter=None): + """Initialize SimulationParameter.""" + self.financial_parameter = financial_parameter + self.wind_parameter = wind_parameter + self.pv_parameter = pv_parameter + self.storage_parameter = storage_parameter + self.generator_parameter = generator_parameter + + @property + def financial_parameter(self): + """Get or set a FinancialParameter object for financial settings.""" + return self._financial_parameter + + @financial_parameter.setter + def financial_parameter(self, value): + if value is not None: + assert isinstance(value, FinancialParameter), 'Expected ' \ + 'FinancialParameter. Got {}.'.format(type(value)) + self._financial_parameter = value + else: + self._financial_parameter = FinancialParameter() + + @property + def wind_parameter(self): + """Get or set a WindParameter object for wind settings.""" + return self._wind_parameter + + @wind_parameter.setter + def wind_parameter(self, value): + if value is not None: + assert isinstance(value, WindParameter), 'Expected ' \ + 'WindParameter. Got {}.'.format(type(value)) + self._wind_parameter = value + else: + self._wind_parameter = WindParameter() + + @property + def pv_parameter(self): + """Get or set a PVParameter object for photovoltaic settings.""" + return self._pv_parameter + + @pv_parameter.setter + def pv_parameter(self, value): + if value is not None: + assert isinstance(value, PVParameter), 'Expected ' \ + 'PVParameter. Got {}.'.format(type(value)) + self._pv_parameter = value + else: + self._pv_parameter = PVParameter() + + @property + def storage_parameter(self): + """Get or set a StorageParameter object for electricity storage settings.""" + return self._storage_parameter + + @storage_parameter.setter + def storage_parameter(self, value): + if value is not None: + assert isinstance(value, StorageParameter), 'Expected ' \ + 'StorageParameter. Got {}.'.format(type(value)) + self._storage_parameter = value + else: + self._storage_parameter = StorageParameter() + + @property + def generator_parameter(self): + """Get or set a GeneratorParameter object for electricity storage settings.""" + return self._generator_parameter + + @generator_parameter.setter + def generator_parameter(self, value): + if value is not None: + assert isinstance(value, GeneratorParameter), 'Expected ' \ + 'GeneratorParameter. Got {}.'.format(type(value)) + self._generator_parameter = value + else: + self._generator_parameter = GeneratorParameter() + +
    +[docs] + def to_assumptions_dict(self, base_file, urdb_label): + """Get REoptParameter as a dictionary representation in the REopt Lite schema. + + Full documentation of the REopt Lite schema can be found at. + https://developer.nrel.gov/docs/energy-optimization/reopt-v1/ + + Args: + base_file: A JSON file in the REopt Lite schema containing a base set + of assumptions that will be modified based on the properties of + this object. + urdb_label: Text string for the Utility Rate Database (URDB) label + for the particular electrical utility rate for the + optimization. The label is the last term of the URL of a + utility rate detail page (eg. the label for the rate at + https://openei.org/apps/IURDB/rate/view/5b0d83af5457a3f276733305 + is 5b0d83af5457a3f276733305). + """ + # load up the base dictionary + assert os.path.isfile(base_file), \ + 'No base JSON file found at {}.'.format(base_file) + with open(base_file, 'r') as base_f: + base_dict = json.load(base_f) + # apply this object's properties + site_dict = base_dict['Scenario']['Site'] + site_dict['ElectricTariff']['urdb_label'] = urdb_label + self.financial_parameter.apply_to_dict(site_dict['Financial']) + self.wind_parameter.apply_to_dict(site_dict['Wind']) + self.pv_parameter.apply_to_dict(site_dict['PV']) + self.storage_parameter.apply_to_dict(site_dict['Storage']) + self.generator_parameter.apply_to_dict(site_dict['Generator']) + return base_dict
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString.""" + return self.__repr__()
    + + + def __copy__(self): + return REoptParameter( + self.financial_parameter.duplicate(), self.wind_parameter.duplicate(), + self.pv_parameter.duplicate(), self.storage_parameter.duplicate(), + self.generator_parameter.duplicate()) + + def __repr__(self): + return 'REoptParameter:'
    + + + +
    +[docs] +class FinancialParameter(object): + """Complete set of Financial settings for REopt. + + Args: + analysis_years: An integer for the number of years over which cost will + be optimized. (Default: 25). + escalation_rate: A number between 0 and 1 for the escalation rate over + the analysis. (Default: 0.023). + tax_rate: A number between 0 and 1 for the rate at which the owner/host + of the system is taxed. (Default: 0.26). + discount_rate: A number between 0 and 1 for the discount rate for the + owner/host of the system. (Default: 0.083). + + Properties: + * analysis_years + * escalation_rate + * tax_rate + * discount_rate + """ + def __init__(self, analysis_years=25, escalation_rate=0.023, + tax_rate=0.26, discount_rate=0.083): + """Initialize FinancialParameter.""" + self.analysis_years = analysis_years + self.escalation_rate = escalation_rate + self.tax_rate = tax_rate + self.discount_rate = discount_rate + + @property + def analysis_years(self): + """Get or set a integer for the number of years to run the analysis.""" + return self._analysis_years + + @analysis_years.setter + def analysis_years(self, value): + self._analysis_years = int_positive( + value, input_name='financial parameter analysis years') + + @property + def escalation_rate(self): + """Get or set a fractional number for the escalation rate.""" + return self._escalation_rate + + @escalation_rate.setter + def escalation_rate(self, value): + self._escalation_rate = float_in_range( + value, 0, 1, input_name='financial parameter escalation rate') + + @property + def tax_rate(self): + """Get or set a fractional number for the tax rate.""" + return self._tax_rate + + @tax_rate.setter + def tax_rate(self, value): + self._tax_rate = float_in_range( + value, 0, 1, input_name='financial parameter tax rate') + + @property + def discount_rate(self): + """Get or set a fractional number for the discount rate.""" + return self._discount_rate + + @discount_rate.setter + def discount_rate(self, value): + self._discount_rate = float_in_range( + value, 0, 1, input_name='financial parameter discount rate') + +
    +[docs] + def apply_to_dict(self, base_dict): + """Apply this object's properties to a 'Financial' object of REopt schema.""" + base_dict['analysis_years'] = self.analysis_years + base_dict['escalation_pct'] = self.escalation_rate + base_dict['offtaker_tax_pct'] = self.tax_rate + base_dict['offtaker_discount_pct'] = self.discount_rate
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString.""" + return self.__repr__()
    + + + def __copy__(self): + return FinancialParameter( + self.analysis_years, self.escalation_rate, self.tax_rate, self.discount_rate) + + def __repr__(self): + return 'REopt FinancialParameter:'
    + + + +class _SourceParameter(object): + """Base class for all REopt energy sources. + + Args: + max_kw: A number for the maximum installed kilowatts of the energy + source. (Default: 0). + dollars_per_kw: A number for the installation cost of the energy source in + US dollars. (Default: 500). + + Properties: + * max_kw + * dollars_per_kw + """ + def __init__(self, max_kw=0, dollars_per_kw=500): + self.max_kw = max_kw + self.dollars_per_kw = dollars_per_kw + + @property + def max_kw(self): + """Get or set a number for the maximum installed kilowatts.""" + return self._max_kw + + @max_kw.setter + def max_kw(self, value): + self._max_kw = float_positive(value, input_name='reopt max kw') + + @property + def dollars_per_kw(self): + """Get or set a number for the installation cost in US dollars.""" + return self._dollars_per_kw + + @dollars_per_kw.setter + def dollars_per_kw(self, value): + self._dollars_per_kw = float_positive(value, input_name='reopt dollars per kw') + + def apply_to_dict(self, base_dict): + """Apply this object's properties to an object of REopt schema.""" + base_dict['max_kw'] = self.max_kw + base_dict['installed_cost_us_dollars_per_kw'] = self.dollars_per_kw + + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__() + + def __copy__(self): + return self.__class__(self.max_kw, self.dollars_per_kw) + + +
    +[docs] +class WindParameter(_SourceParameter): + """Wind settings for REopt. + + Args: + max_kw: A number for the maximum installed kilowatts. (Default: 0). + dollars_per_kw: A number for installation cost in US dollars. (Default: 3013). + + Properties: + * max_kw + * dollars_per_kw + """ + def __init__(self, max_kw=0, dollars_per_kw=3013): + _SourceParameter.__init__(self, max_kw, dollars_per_kw) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString.""" + return self.__repr__()
    + + + def __repr__(self): + return 'REopt WindParameter: {} kW'.format(self.max_kw)
    + + + +
    +[docs] +class PVParameter(_SourceParameter): + """Photovoltaic settings for REopt. + + Args: + max_kw: A number for the maximum installed kilowatts. (Default: 0). + dollars_per_kw: A number for installation cost in US dollars. (Default: 1600). + + Properties: + * max_kw + * dollars_per_kw + * max_kw_ground + * dollars_per_kw_ground + """ + def __init__(self, max_kw=0, dollars_per_kw=1600, + max_kw_ground=0, dollars_per_kw_ground=2200): + _SourceParameter.__init__(self, max_kw, dollars_per_kw) + self.max_kw_ground = max_kw_ground + self.dollars_per_kw_ground = dollars_per_kw_ground + + @property + def max_kw_ground(self): + """Get or set a number for the maximum installed kilowatts of Ground PV.""" + return self._max_kw_ground + + @max_kw_ground.setter + def max_kw_ground(self, value): + self._max_kw_ground = float_positive(value, input_name='reopt max kw') + + @property + def dollars_per_kw_ground(self): + """Get or set a number for the installation cost of ground PV in US dollars.""" + return self._dollars_per_kw_ground + + @dollars_per_kw_ground.setter + def dollars_per_kw_ground(self, value): + self._dollars_per_kw_ground = \ + float_positive(value, input_name='reopt dollars per kw') + +
    +[docs] + def apply_to_dict(self, base_dict): + """Apply this object's properties to an object of REopt schema.""" + if isinstance(base_dict, dict): + base_dict['max_kw'] = self.max_kw + base_dict['installed_cost_us_dollars_per_kw'] = self.dollars_per_kw + else: + base_dict[0]['max_kw'] = self.max_kw + base_dict[0]['installed_cost_us_dollars_per_kw'] = self.dollars_per_kw + base_dict[1]['max_kw'] = self.max_kw_ground + base_dict[1]['installed_cost_us_dollars_per_kw'] = self.dollars_per_kw_ground
    + + + def __copy__(self): + return PVParameter(self.max_kw, self.dollars_per_kw, + self.max_kw_ground, self.dollars_per_kw_ground) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString.""" + return self.__repr__()
    + + + def __repr__(self): + return 'REopt PVParameter: {} kW'.format(self.max_kw)
    + + + +
    +[docs] +class StorageParameter(_SourceParameter): + """Electrical storage settings for REopt. + + Args: + max_kw: A number for the maximum installed kilowatts. (Default: 0). + dollars_per_kw: A number for installation cost in US dollars. (Default: 840). + + Properties: + * max_kw + * dollars_per_kw + """ + def __init__(self, max_kw=0, dollars_per_kw=840): + _SourceParameter.__init__(self, max_kw, dollars_per_kw) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString.""" + return self.__repr__()
    + + + def __repr__(self): + return 'REopt StorageParameter: {} kW'.format(self.max_kw)
    + + + +
    +[docs] +class GeneratorParameter(_SourceParameter): + """Generator settings for REopt. + + Args: + max_kw: A number for the maximum installed kilowatts. (Default: 0). + dollars_per_kw: A number for installation cost in US dollars. (Default: 500). + + Properties: + * max_kw + * dollars_per_kw + """ + def __init__(self, max_kw=0, dollars_per_kw=500): + _SourceParameter.__init__(self, max_kw, dollars_per_kw) + +
    +[docs] + def ToString(self): + """Overwrite .NET ToString.""" + return self.__repr__()
    + + + def __repr__(self): + return 'REopt GeneratorParameter: {} kW'.format(self.max_kw)
    + + + +
    +[docs] +class GroundMountPV(object): + """Represents a ground-mounted photovoltaic system in REopt. + + Args: + identifier: Text string for a unique Photovoltaic ID. Must contain only + characters that are acceptable in REopt. This will be used to + identify the object across the exported geoJSON and REopt files. + geometry: A Polygon2D representing the geometry of the PV field. + building_identifier: An optional identifier of a dragonfly Building with + which the photovoltaic system is associated. If None, the PV system + will be assumed to be a community PV field that isn't associated with + a particular building meter. (Default: None). + + Properties: + * identifier + * display_name + * geometry + * building_identifier + """ + __slots__ = ('_identifier', '_display_name', '_geometry', '_building_identifier') + + def __init__(self, identifier, geometry, building_identifier=None): + """Initialize GroundMountPV.""" + self.identifier = identifier + self._display_name = None + assert isinstance(geometry, Polygon2D), 'Expected ladybug_geometry ' \ + 'Polygon2D for GroundMountPV geometry. Got {}'.format(type(geometry)) + self._geometry = geometry + self.building_identifier = building_identifier + +
    +[docs] + @classmethod + def from_dict(cls, data): + """Initialize an GroundMountPV from a dictionary. + + Args: + data: A dictionary representation of an GroundMountPV object. + """ + # check the type of dictionary + assert data['type'] == 'GroundMountPV', 'Expected GroundMountPV ' \ + 'dictionary. Got {}.'.format(data['type']) + geo = Polygon2D.from_dict(data['geometry']) + pv_obj = cls(data['identifier'], geo) + if 'display_name' in data and data['display_name'] is not None: + pv_obj.display_name = data['display_name'] + if 'building_identifier' in data and data['building_identifier'] is not None: + pv_obj.building_identifier = data['building_identifier'] + return pv_obj
    + + + @property + def identifier(self): + """Get or set the text string for unique object identifier.""" + return self._identifier + + @identifier.setter + def identifier(self, identifier): + self._identifier = valid_ep_string(identifier, 'identifier') + + @property + def display_name(self): + """Get or set a string for the object name without any character restrictions. + + If not set, this will be equal to the identifier. + """ + if self._display_name is None: + return self._identifier + return self._display_name + + @display_name.setter + def display_name(self, value): + try: + self._display_name = str(value) + except UnicodeEncodeError: # Python 2 machine lacking the character set + self._display_name = value # keep it as unicode + + @property + def building_identifier(self): + """Get or set the text string for a Building associated with the PV field.""" + return self._building_identifier + + @building_identifier.setter + def building_identifier(self, identifier): + if identifier is not None: + identifier = valid_string(identifier, 'building identifier') + self._building_identifier = identifier + + @property + def geometry(self): + """Get a Polygon2D representing the photovoltaic field.""" + return self._geometry + +
    +[docs] + def move(self, moving_vec): + """Move this object along a vector. + + Args: + moving_vec: A ladybug_geometry Vector3D with the direction and distance + to move the object. + """ + self._geometry = self._geometry.move(Vector2D(moving_vec.x, moving_vec.y))
    + + +
    +[docs] + def rotate_xy(self, angle, origin): + """Rotate this object counterclockwise in the XY plane by a certain angle. + + Args: + angle: An angle in degrees. + origin: A ladybug_geometry Point3D for the origin around which the + object will be rotated. + """ + self._geometry = self._geometry.rotate( + math.radians(angle), Point2D(origin.x, origin.y))
    + + +
    +[docs] + def reflect(self, plane): + """Reflect this object across a plane. + + Args: + plane: A ladybug_geometry Plane across which the object will be reflected. + """ + assert plane.n.z == 0, \ + 'Plane normal must be in XY plane to use it on dragonfly object reflect.' + norm = Vector2D(plane.n.x, plane.n.y) + origin = Point2D(plane.o.x, plane.o.y) + self._geometry = self._geometry.reflect(norm, origin)
    + + +
    +[docs] + def scale(self, factor, origin=None): + """Scale this object by a factor from an origin point. + + Args: + factor: A number representing how much the object should be scaled. + origin: A ladybug_geometry Point3D representing the origin from which + to scale. If None, it will be scaled from the World origin (0, 0, 0). + """ + ori = Point2D(origin.x, origin.y) if origin is not None else None + self._geometry = self._geometry.scale(factor, ori)
    + + +
    +[docs] + def to_dict(self): + """GroundMountPV dictionary representation.""" + base = {'type': 'GroundMountPV'} + base['identifier'] = self.identifier + base['geometry'] = self.geometry.to_dict() + if self._display_name is not None: + base['display_name'] = self.display_name + if self._building_identifier is not None: + base['building_identifier'] = self.building_identifier + return base
    + + +
    +[docs] + def to_geojson_dict(self, location, point): + """Get GroundMountPV dictionary as it appears in an URBANopt geoJSON. + + Args: + location: A ladybug Location object possessing longitude and latitude data. + point: A ladybug_geometry Point2D for where the location object exists + within the space of a scene. The coordinates of this point are + expected to be in the units of this Model. (Default: (0, 0)). + """ + # get the conversion factors over to (longitude, latitude) + origin_lon_lat = origin_long_lat_from_location(location, point) + convert_facs = meters_to_long_lat_factors(origin_lon_lat) + + # create the GeoJSON dictionary + pts = [(pt.x, pt.y) for pt in self.geometry.vertices] + coords = [polygon_to_lon_lat(pts, origin_lon_lat, convert_facs)] + base = { + 'type': 'Feature', + 'properties': { + 'id': self.identifier, + 'geometryType': 'Rectangle', + 'name': self.display_name, + 'type': 'District System', + 'footprint_area': self.geometry.area, + 'footprint_perimeter': self.geometry.perimeter + }, + 'geometry': { + 'type': 'Polygon', + 'coordinates': coords + } + } + if self.building_identifier is None: + base['properties']['district_system_type'] = 'Community Photovoltaic' + else: + base['properties']['district_system_type'] = 'Ground Mount Photovoltaic' + base['properties']['associated_building_id'] = self.building_identifier + return base
    + + +
    +[docs] + def duplicate(self): + """Get a copy of this object.""" + return self.__copy__()
    + + + def __copy__(self): + new_obj = GroundMountPV(self.identifier, self.geometry, self.building_identifier) + new_obj._display_name = self._display_name + return new_obj + +
    +[docs] + def ToString(self): + return self.__repr__()
    + + + def __repr__(self): + return 'GroundMountPV: {}'.format(self.display_name)
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/run.html b/docs/_modules/dragonfly_energy/run.html new file mode 100644 index 00000000..f7d45dc9 --- /dev/null +++ b/docs/_modules/dragonfly_energy/run.html @@ -0,0 +1,2361 @@ + + + + + + + dragonfly_energy.run — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.run

    +# coding=utf-8
    +"""Module for running geoJSON and OpenStudio files through URBANopt."""
    +from __future__ import division
    +
    +import os
    +import json
    +import shutil
    +import subprocess
    +
    +from ladybug.futil import preparedir, write_to_file
    +from ladybug.epw import EPW
    +from ladybug.config import folders as lb_folders
    +from honeybee.config import folders as hb_folders
    +from honeybee_energy.config import folders as hb_energy_folders
    +from honeybee_energy.result.emissions import emissions_region
    +
    +from .config import folders
    +from .measure import MapperMeasure
    +from .reopt import REoptParameter
    +
    +# Custom environment used to run Python packages without conflicts
    +PYTHON_ENV = os.environ.copy()
    +PYTHON_ENV['PYTHONHOME'] = ''
    +
    +# Number to prevent GHE Designer simulations that would max out the memory
    +MAX_BOREHOLES = 10000
    +
    +
    +
    +[docs] +def base_honeybee_osw( + project_directory, sim_par_json=None, additional_measures=None, + additional_mapper_measures=None, base_osw=None, epw_file=None, + skip_report=True, emissions_year=None): + """Create a honeybee_workflow.osw to be used as a base in URBANopt simulations. + + This method will also copy the Honeybee.rb mapper to this folder if it is + available in the config of this library. + + Args: + project_directory: Full path to a folder out of which the URBANopt simulation + will be run. This is the folder that contains the feature geoJSON. + sim_par_json: Optional file path to the SimulationParameter JSON. + If None, the OpenStudio models generated in the URBANopt run will + not have everything they need to be simulate-able unless such + parameters are supplied from one of the additional_measures or the + base_osw. (Default: None). + additional_measures: An optional array of honeybee-energy Measure objects + to be included in the output osw. These Measure objects must have + values for all required input arguments or an exception will be + raised while running this function. (Default: None). + additional_mapper_measures: An optional array of dragonfly-energy MapperMeasure + objects to be included in the output osw. These MapperMeasure objects + must have values for all required input arguments or an exception will + be raised while running this function. (Default: None). + base_osw: Optional file path to an existing OSW JSON be used as the base + for the honeybee_workflow.osw. This is another way that outside measures + can be incorporated into the workflow. (Default: None). + epw_file: Optional file path to an EPW that should be associated with the + output energy model. (Default: None). + skip_report: Set to True to have the URBANopt default feature reporting + measure skipped as part of the workflow. If False, the measure will + be run after all simulations are complete. Note that this input + has no effect if the default_feature_reports measure is already + in the base_osw or additional_measures. (Default: True). + emissions_year: An optional integer to set the year for which carbon emissions + will be computed. If not for a historical year, values must be an even + number and be between 2020 and 2050. If None, no carbon emission + calculations will be included in the simulation. (Default: None). + + Returns: + The file path to the honeybee_workflow.osw written out by this method. + This is used as the base for translating all features in the geoJSON. + """ + # create a dictionary representation of the .osw with steps to run + # the model measure and the simulation parameter measure + if base_osw is None: + osw_dict = {'steps': [], 'name': None, 'description': None} + else: + assert os.path.isfile(base_osw), 'No base OSW file found at {}.'.format(base_osw) + with open(base_osw, 'r') as base_file: + osw_dict = json.load(base_file) + + # add a simulation parameter step if it is specified + if sim_par_json is not None: + sim_par_dict = { + 'arguments': { + 'simulation_parameter_json': sim_par_json + }, + 'measure_dir_name': 'from_honeybee_simulation_parameter' + } + osw_dict['steps'].insert(0, sim_par_dict) + + # add the model json serialization into the steps + model_measure_dict = { + 'arguments': { + 'model_json': 'model_json_to_be_mapped.json' + }, + 'measure_dir_name': 'from_honeybee_model' + } + osw_dict['steps'].insert(0, model_measure_dict) + + # assign the measure_paths to the osw_dict + if 'measure_paths' not in osw_dict: + osw_dict['measure_paths'] = [] + if hb_energy_folders.honeybee_openstudio_gem_path: # add honeybee-openstudio measure + m_dir = os.path.join(hb_energy_folders.honeybee_openstudio_gem_path, 'measures') + osw_dict['measure_paths'].append(m_dir) + + # add the emissions reporting if a year has been selected + if emissions_year is not None and epw_file is not None: + epw_obj = EPW(epw_file) + ems_region = emissions_region(epw_obj.location) + if ems_region is not None: + if emissions_year < 2020: + hist_yr, fut_yr = emissions_year, 2030 + else: + hist_yr, fut_yr = 2019, emissions_year + emissions_measure_dict = { + 'arguments': { + 'future_subregion': ems_region[0], + 'hourly_historical_subregion': ems_region[2], + 'annual_historical_subregion': ems_region[1], + 'future_year': str(fut_yr), + 'hourly_historical_year': '2019', + 'annual_historical_year': str(hist_yr) + }, + 'measure_dir_name': 'add_ems_emissions_reporting' + } + osw_dict['steps'].append(emissions_measure_dict) + + # add any additional measures to the osw_dict + if additional_measures or additional_mapper_measures: + measures = [] + if additional_measures is not None: + measures.extend(additional_measures) + if additional_mapper_measures is not None: + measures.extend(additional_mapper_measures) + measure_paths = set() # set of all unique measure paths + # ensure measures are correctly ordered + m_dict = {'ModelMeasure': [], 'EnergyPlusMeasure': [], 'ReportingMeasure': []} + for measure in measures: + m_dict[measure.type].append(measure) + sorted_measures = m_dict['ModelMeasure'] + m_dict['EnergyPlusMeasure'] + \ + m_dict['ReportingMeasure'] + for measure in sorted_measures: + measure.validate() # ensure that all required arguments have values + measure_paths.add(os.path.dirname(measure.folder)) + osw_dict['steps'].append(measure.to_osw_dict()) # add measure to workflow + if isinstance(measure, MapperMeasure): + _add_mapper_measure(project_directory, measure) + for m_path in measure_paths: # add outside measure paths + osw_dict['measure_paths'].append(m_path) + + # add default feature reports if they aren't in the steps + all_measures = [step['measure_dir_name'] for step in osw_dict['steps']] + if 'default_feature_reports' not in all_measures: + report_measure_dict = { + 'arguments': { + 'feature_id': None, + 'feature_name': None, + 'feature_type': None, + 'feature_location': None + }, + 'measure_dir_name': 'default_feature_reports' + } + if skip_report: + report_measure_dict['arguments']['__SKIP__'] = True + osw_dict['steps'].append(report_measure_dict) + + # if there is a system parameter JSON, make sure the EPW is copied and referenced + if epw_file is not None: + osw_dict['weather_file'] = epw_file + sys_param_file = os.path.join(project_directory, 'system_params.json') + if os.path.isfile(sys_param_file): + # make sure the Modelica measure runs as part of the simulation + modelica_measures = [ + { + 'measure_dir_name': 'export_time_series_modelica', + 'arguments': {'__SKIP__': False} + }, + { + 'measure_dir_name': 'export_modelica_loads', + 'arguments': {'__SKIP__': False} + }, + ] + osw_dict['steps'].extend(modelica_measures) + + # copy the EPW to the project directory + epw_f_name = os.path.split(epw_file)[-1] + target_epw = os.path.join(project_directory, epw_f_name) + shutil.copy(epw_file, target_epw) + # create a MOS file from the EPW + epw_obj = EPW(target_epw) + mos_file = os.path.join( + project_directory, epw_f_name.replace('.epw', '.mos')) + epw_obj.to_mos(mos_file) + # find the path to the feature GeoJSON + feature_geojson = None + for fp in os.listdir(project_directory): + if fp.endswith('.geojson'): + feature_geojson = os.path.join(project_directory, fp) + break + if not feature_geojson: + raise ValueError( + 'No feature geojson file was found in: {}'.format(project_directory)) + # write the EPW path into the GeoJSON + with open(feature_geojson, 'r') as gjf: + geo_dict = json.load(gjf) + if 'project' in geo_dict: + if 'weather_filename' not in geo_dict['project']: + geo_dict['project']['weather_filename'] = epw_f_name + with open(feature_geojson, 'w') as fp: + json.dump(geo_dict, fp, indent=4) + + # if the DES system is GSHP, specify any autocalculated ground temperatures + with open(sys_param_file, 'r') as spf: + sys_dict = json.load(spf) + if 'district_system' in sys_dict: + if 'fifth_generation' in sys_dict['district_system']: + g5_par = sys_dict['district_system']['fifth_generation'] + if 'soil' in g5_par and 'undisturbed_temp' in g5_par['soil']: + soil_par = g5_par['soil'] + if soil_par['undisturbed_temp'] == 'Autocalculate': + epw_obj = EPW(epw_file) + soil_par['undisturbed_temp'] = \ + epw_obj.dry_bulb_temperature.average + with open(sys_param_file, 'w') as fp: + json.dump(sys_dict, fp, indent=4) + + # write the dictionary to a honeybee_workflow.osw + mappers_dir = os.path.join(project_directory, 'mappers') + if not os.path.isdir(mappers_dir): + preparedir(mappers_dir) + osw_json = os.path.join(mappers_dir, 'honeybee_workflow.osw') + with open(osw_json, 'w') as fp: + json.dump(osw_dict, fp, indent=4) + + # copy the Honeybee.rb mapper if it exists in the config + if folders.mapper_path: + shutil.copy(folders.mapper_path, os.path.join(mappers_dir, 'Honeybee.rb')) + + return os.path.abspath(osw_json)
    + + + +
    +[docs] +def prepare_urbanopt_folder(feature_geojson, cpu_count=None, verbose=False): + """Prepare a directory with a feature geoJSON for URBANopt simulation. + + This includes copying the Gemfile to the folder and generating the runner.conf + to specify the number of CPUs to be used in the simulation. Lastly, the + the scenario .csv file will be generated from the feature_geojson. + + Args: + feature_geojson: An URBANopt feature geoJSON to be prepared for URBANopt + simulation. + cpu_count: A positive integer for the number of CPUs to use in the + simulation. This number should not exceed the number of CPUs on the + machine running the simulation and should be lower if other tasks + are running while the simulation is running. If set to None, it + should automatically default to one less than the number of CPUs + currently available on the machine (or 1 if the machine has only + one processor). (Default: None). + verbose: Boolean to note if the simulation should be run with verbose + reporting of progress. (Default: False). + + Returns: + Path to the .csv file for the URBANopt scenario. + """ + # copy the Gemfile into the folder containing the feature_geojson + assert folders.urbanopt_gemfile_path, \ + 'No URBANopt Gemfile was found in dragonfly_energy.config.folders.\n' \ + 'This file must exist to run URBANopt.' + folders.check_urbanopt_version() + uo_folder = os.path.dirname(feature_geojson) + shutil.copy(folders.urbanopt_gemfile_path, os.path.join(uo_folder, 'Gemfile')) + + # auto-assign the number of processors if None + cpu_count = _recommended_processor_count() if cpu_count is None else cpu_count + + # generate the runner.conf to set the number of CPUs based on the input + runner_dict = { + 'file_version': '0.1.0', + 'max_datapoints': 1000000000, + 'num_parallel': cpu_count, + 'run_simulations': True, + 'verbose': verbose + } + runner_conf = os.path.join(uo_folder, 'runner.conf') + with open(runner_conf, 'w') as fp: + json.dump(runner_dict, fp, indent=2) + + # generate the scenario csv file + return _make_scenario(feature_geojson)
    + + + +
    +[docs] +def run_urbanopt(feature_geojson, scenario_csv, cpu_count=None): + """Run a feature and scenario file through URBANopt on any operating system. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + cpu_count: This input is deprecated and currently not used given that + the runner.conf generated in the prepare_urbanopt_folder step + correctly identifies the number of CPUs to be used. + + Returns: + A series of file paths to the simulation output files + + - osm -- Array of paths to .osm files for all generated OpenStudio models. + + - idf -- Array of paths to .idf files containing the input for the + EnergyPlus simulation. + + - sql -- Array of paths to .sqlite files containing all simulation results. + + - zsz -- Array of paths to .csv files containing detailed zone load + information recorded over the course of the design days. + + - rdd -- Array of paths to .rdd files containing all possible outputs + that can be requested from the simulation. + + - html -- Array of paths to .html files containing all summary reports. + + - err -- Array of paths to .err files containing all errors and warnings + from the simulation. + """ + folders.check_urbanopt_version() + # run the simulation + if os.name == 'nt': # we are on Windows + directory, stderr = \ + _run_urbanopt_windows(feature_geojson, scenario_csv) + else: # we are on Mac, Linux, or some other unix-based system + directory, stderr = \ + _run_urbanopt_unix(feature_geojson, scenario_csv) + + # output the simulation files + return _output_urbanopt_files(directory, stderr)
    + + + +
    +[docs] +def run_default_report(feature_geojson, scenario_csv): + """Generate default reports after an URBANopt simulation is run. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + A series of file paths to the report output files + + - csv -- Path to a CSV file containing default scenario results. + + - report_json -- Path to a JSON file containing default scenario results. + """ + folders.check_urbanopt_version() + assert os.path.isfile(feature_geojson), \ + 'No feature_geojson as found at the specified path: {}.'.format(feature_geojson) + assert os.path.isfile(scenario_csv), \ + 'No scenario_csv as found at the specified path: {}.'.format(scenario_csv) + # run the report command + if os.name == 'nt': # we are on Windows + return _run_default_report_windows(feature_geojson, scenario_csv) + else: # we are on Mac, Linux, or some other unix-based system + return _run_default_report_unix(feature_geojson, scenario_csv)
    + + + +
    +[docs] +def run_reopt(feature_geojson, scenario_csv, urdb_label, reopt_parameters=None, + developer_key=None): + """Run a feature and scenario file through REopt post processing. + + Note that the URBANopt simulation must already be run with the input feature_geojson + and scenario_csv in order for the post-processing to be successful. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + urdb_label: Text string for the Utility Rate Database (URDB) label for the + particular electrical utility rate for the optimization. The label is + the last term of the URL of a utility rate detail page (eg. the label for + the rate at https://openei.org/apps/IURDB/rate/view/5b0d83af5457a3f276733305 + is 5b0d83af5457a3f276733305). Utility rates for specific locations + can be looked up in the REopt Lite tool (https://reopt.nrel.gov/tool) + and the label can be obtained by clicking on "Rate Details" link + for a particular selected rate. + reopt_parameters: A REoptParameter object to describe the major assumptions + of the REopt analysis. If None some default parameters will be + generated for a typical analysis. (Default: None). + developer_key: Text string for the NREL developer key. You can get a developer + key at (https://developer.nrel.gov/). (Default: None). + + Returns: + A series of file paths to the simulation output files + + - csv -- Path to a CSV file containing scenario optimization results. + + - report_json -- Path to a JSON file containing scenario optimization results. + """ + # run checks on the inputs + folders.check_urbanopt_version() + assert folders.reopt_assumptions_path, \ + 'No REopt assumptions were found in dragonfly_energy.config.folders.' + assert os.path.isfile(feature_geojson), \ + 'No feature_geojson as found at the specified path: {}.'.format(feature_geojson) + assert os.path.isfile(scenario_csv), \ + 'No scenario_csv as found at the specified path: {}.'.format(scenario_csv) + developer_key = developer_key if developer_key is not None \ + else 'bo8jGuFfk7DBDpTlzShuxWuAGletBq1j5AhcUhCD' + project_folder = os.path.dirname(feature_geojson) + + # write the parameter file + if reopt_parameters is None: # generate some defaults + reopt_parameters = REoptParameter() + reopt_parameters.pv_parameter.max_kw = 1000000000 + reopt_parameters.storage_parameter.max_kw = 1000000 + reopt_parameters.generator_parameter.max_kw = 1000000000 + else: + assert isinstance(reopt_parameters, REoptParameter), \ + 'Expected REoptParameter. Got {}.'.format(type(reopt_parameters)) + reopt_folder = os.path.join(project_folder, 'reopt') + if not os.path.isdir(reopt_folder): + os.mkdir(reopt_folder) + reopt_par_json = os.path.join(reopt_folder, 'reopt_assumptions.json') + reopt_dict = reopt_parameters.to_assumptions_dict( + folders.reopt_assumptions_path, urdb_label) + with open(reopt_par_json, 'w') as fp: + json.dump(reopt_dict, fp, indent=4) + + # run the simulation + if os.name == 'nt': # we are on Windows + directory = _run_reopt_windows(feature_geojson, scenario_csv, developer_key) + else: # we are on Mac, Linux, or some other unix-based system + directory = _run_reopt_unix(feature_geojson, scenario_csv, developer_key) + + # output the simulation files + return _output_reopt_files(directory)
    + + + +
    +[docs] +def run_rnm(feature_geojson, scenario_csv, underground_ratio=0.9, lv_only=True, + nodes_per_building=1): + """Run a feature and scenario file through RNM post processing. + + Note that the URBANopt simulation must already be run with the input feature_geojson + and scenario_csv in order for the RNM post-processing to be successful. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + underground_ratio: A number between 0 and 1 for the ratio of overall cables + that are underground vs. overhead in the analysis. (Default: 0.9). + lv_only: Boolean to note whether to consider only low voltage consumers + in the analysis. (Default: True). + nodes_per_building: Positive integer for the maximum number of low voltage + nodes to represent a single building. (Default: 1). + + Returns: + Path to a folder that contains all of the RNM output files. + """ + # load the information from the GeoJSON + geo_dict, project_dict = None, None + if os.path.isfile(feature_geojson): + with open(feature_geojson, 'r') as fg: + geo_dict = json.load(fg) + project_dict = geo_dict['project'] + # change the GeoJSON to have the RNM inputs + if geo_dict is not None: + proj = geo_dict['project'] + if 'underground_cables_ratio' not in proj or \ + proj['underground_cables_ratio'] != underground_ratio or \ + 'only_lv_consumers' not in proj or \ + proj['only_lv_consumers'] != lv_only or \ + 'max_number_of_lv_nodes_per_building' not in proj or \ + proj['max_number_of_lv_nodes_per_building'] != nodes_per_building: + geo_dict['project']['underground_cables_ratio'] = underground_ratio + geo_dict['project']['only_lv_consumers'] = lv_only + geo_dict['project']['max_number_of_lv_nodes_per_building'] = \ + nodes_per_building + with open(feature_geojson, 'w') as fp: + json.dump(geo_dict, fp, indent=4) + # run the simulation + folders.check_urbanopt_version() + if os.name == 'nt': # we are on Windows + directory = _run_rnm_windows(feature_geojson, scenario_csv) + else: # we are on Mac, Linux, or some other unix-based system + directory = _run_rnm_unix(feature_geojson, scenario_csv) + # get the path to the results folder + scenario_name = os.path.basename(scenario_csv).replace('.csv', '') + rnm_path = os.path.join(directory, 'run', scenario_name, 'rnm-us', 'results') + # copy the project information into the RNM GeoJSON + if os.path.isdir(rnm_path): + rnm_geojson = os.path.join(rnm_path, 'GeoJSON', 'Distribution_system.json') + with open(rnm_geojson, 'r') as fg: + rnm_dict = json.load(fg) + rnm_dict['project'] = project_dict + with open(rnm_geojson, 'w') as fp: + json.dump(rnm_dict, fp, indent=4) + return rnm_path
    + + + +
    +[docs] +def run_des_sys_param(feature_geojson, scenario_csv): + """Run the GMT command to add the time series building loads to the sys param JSON. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + """ + # get the directory and parse the system parameter file + directory = os.path.dirname(feature_geojson) + sys_param_file = os.path.join(directory, 'system_params.json') + assert os.path.isfile(sys_param_file), \ + 'No DES system parameter was found for this model.\n' \ + 'Make sure that the des_loop_ was assigned in the GeoJSON export\n' \ + 'before running the URBANopt simulation.' + + # parse the system parameter file to understand the type of system + with open(sys_param_file, 'r') as spf: + sp_dict = json.load(spf) + des_dict = sp_dict['district_system'] + ghe_sys = True if 'fifth_generation' in des_dict and \ + 'ghe_parameters' in des_dict['fifth_generation'] else False + + # run the command that adds the building loads to the system parameter + ext = '.exe' if os.name == 'nt' else '' + shell = True if os.name == 'nt' else False + uo_des_exe = os.path.join( + hb_folders.python_scripts_path, 'uo_des{}'.format(ext)) + build_cmd = '"{des_exe}" build-sys-param ' \ + '"{sp_file}" "{scenario}" "{feature}" '.format( + des_exe=uo_des_exe, sp_file=sys_param_file, + scenario=scenario_csv, feature=feature_geojson) + if ghe_sys: + build_cmd = '{} 5G_ghe'.format(build_cmd) + else: + build_cmd = '{} 4G'.format(build_cmd) + build_cmd = '{} time_series -o'.format(build_cmd) + process = subprocess.Popen( + build_cmd, stderr=subprocess.PIPE, shell=shell, env=PYTHON_ENV + ) + stderr = process.communicate() + if not os.path.isfile(sys_param_file): + msg = 'Failed to add building loads to the DES system parameter file.\n' \ + 'No file found at:\n{}\n{}'.format(sys_param_file, stderr[1]) + print(msg) + raise Exception(msg) + else: + print(stderr[1]) + + # after the loads have been added, put pack the properties of the DES + with open(sys_param_file, 'r') as spf: + sp_dict = json.load(spf) + if ghe_sys: + original_des_par = des_dict['fifth_generation'] + original_ghe_par = original_des_par['ghe_parameters'] + des_par = sp_dict['district_system']['fifth_generation'] + des_par['soil'] = original_des_par['soil'] + des_par['ghe_parameters']['fluid'] = original_ghe_par['fluid'] + des_par['ghe_parameters']['grout'] = original_ghe_par['grout'] + des_par['ghe_parameters']['pipe'] = original_ghe_par['pipe'] + des_par['ghe_parameters']['geometric_constraints'] = \ + original_ghe_par['geometric_constraints'] + des_par['ghe_parameters']['ghe_specific_params'] = \ + original_ghe_par['ghe_specific_params'] + # remove geometric params so that ThermalNetwork uses GeoJSON polygon + rect_geo_par = [] + for ghe_dict in des_par['ghe_parameters']['ghe_specific_params']: + rect_geo_par.append(ghe_dict.pop('ghe_geometric_params')) + else: + sp_dict['district_system'] = des_dict + with open(sys_param_file, 'w') as spf: + json.dump(sp_dict, spf, indent=2) + + # if the DES system has a ground heat exchanger, run the thermal network package + if ghe_sys: + # run the GHE Designer to size the system + tn_exe = os.path.join( + hb_folders.python_scripts_path, 'thermalnetwork{}'.format(ext)) + scn_name = os.path.basename(scenario_csv).replace('.csv', '') + scn_dir = os.path.join(directory, 'run', scn_name) + ghe_dir = os.path.join(scn_dir, 'ghe_dir') + build_cmd = \ + '"{tn_exe}" -y "{sp_file}" -s "{scenario}" -f "{feature}" -o {out_p}'.format( + tn_exe=tn_exe, sp_file=sys_param_file, + scenario=scn_dir, feature=feature_geojson, out_p=ghe_dir) + process = subprocess.Popen( + build_cmd, stderr=subprocess.PIPE, shell=False, env=PYTHON_ENV + ) + # if any errors were found in the sizing simulation, raise them to the user + stderr = process.communicate()[1] + stderr_str = str(stderr.strip()) + print(stderr_str) + if 'ValueError' in stderr_str: # pass the exception onto the user + msg = stderr_str.split('ValueError: ')[-1].strip() + raise ValueError(msg) + # add the borehole length and count to the system parameter file + with open(sys_param_file, 'r') as spf: + sp_dict = json.load(spf) + ghe_par_dict = sp_dict['district_system']['fifth_generation']['ghe_parameters'] + for ghe_s_par, rect_par in zip(ghe_par_dict['ghe_specific_params'], rect_geo_par): + r_dir = des_par['ghe_parameters']['ghe_dir'] + res_file = os.path.join(r_dir, ghe_s_par['ghe_id'], 'SimulationSummary.json') + with open(res_file, 'r') as rf: + res_dict = json.load(rf) + ghe_s_par['borehole']['length_of_boreholes'] = \ + res_dict['ghe_system']['active_borehole_length']['value'] + ghe_s_par['borehole']['number_of_boreholes'] = \ + res_dict['ghe_system']['number_of_boreholes'] + ghe_s_par['ghe_geometric_params'] = rect_par + with open(sys_param_file, 'w') as spf: + json.dump(sp_dict, spf, indent=2) + return sys_param_file
    + + + +
    +[docs] +def run_des_modelica(sys_param_json, feature_geojson, scenario_csv): + """Run the GMT command to create the Modelica files from the system param JSON. + + Args: + sys_param_json: The full path to a system parameter JSON from which the + Modelica files will be generated. + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + The path to the folder where the Modelica files have been written. + """ + # run the simulation + if os.name == 'nt': # we are on Windows + modelica_dir, stderr = \ + _generate_modelica_windows(sys_param_json, feature_geojson, scenario_csv) + else: # we are on Mac, Linux, or some other unix-based system + modelica_dir, stderr = \ + _generate_modelica_unix(sys_param_json, feature_geojson, scenario_csv) + if not os.path.isdir(modelica_dir): + msg = 'Failed to translate DES to Modelica.\n' \ + 'No results were found at:\n{}\n{}'.format(modelica_dir, stderr) + print(msg) + raise Exception(msg) + else: + _add_water_heating_patch(modelica_dir) + return modelica_dir
    + + + +
    +[docs] +def run_modelica_docker(modelica_project_dir): + """Execute Modelica files of a DES. + + Args: + modelica_project_dir: The full path to the folder in which the Modelica + files were written. + + Returns: + The path to where the results have been written. + """ + # run the simulation + if os.name == 'nt': # we are on Windows + modelica_dir, stderr = _run_modelica_windows(modelica_project_dir) + else: # we are on Mac, Linux, or some other unix-based system + modelica_dir, stderr = _run_modelica_unix(modelica_project_dir) + if not os.path.isdir(modelica_dir): + msg = 'Failed to execute Modelica simulation.\n' \ + 'No results were found at:\n{}\n{}'.format(modelica_dir, stderr) + print(msg) + raise Exception(msg) + return modelica_dir
    + + + +def _add_mapper_measure(project_directory, mapper_measure): + """Add mapper measure arguments to a geoJSON and the mapper_measures.json. + + Args: + project_directory: Full path to a folder out of which the URBANopt simulation + will be run. This is the folder that contains the feature geoJSON. + mapper_measure: A MapperMeasure object to add. + """ + # find the feature geoJSON and parse in the dictionary + for proj_file in os.listdir(project_directory): + if proj_file.endswith('geojson'): + geojson_file = os.path.join(project_directory, proj_file) + break + with open(geojson_file, 'r') as base_file: + geojson_dict = json.load(base_file) + + # find or start the mapper_measures.json + mapper_dir = os.path.join(project_directory, 'mappers') + map_meas_file = os.path.join(mapper_dir, 'mapper_measures.json') + if os.path.isfile(map_meas_file): + with open(map_meas_file, 'r') as base_file: + map_meas_list = json.load(base_file) + else: + map_meas_list = [] + + # loop through the mapper measure and assign any mapper arguments + for m_arg in mapper_measure.arguments: + if isinstance(m_arg.value, tuple): # argument to map to buildings + for i, feat in enumerate(geojson_dict['features']): + try: + if feat['properties']['type'] == 'Building': + feat['properties'][m_arg.identifier] = m_arg.value[i] + except IndexError: + raise ValueError( + 'Number of MapperMeasure arguments ({}) does not equal the ' + 'number of buildings in the model ({}).'.format( + len(m_arg.value), len(geojson_dict['features']))) + except KeyError: # definitely not a building + pass + m_arg_info = [ + os.path.basename(mapper_measure.folder), + m_arg.identifier, m_arg.identifier] + map_meas_list.append(m_arg_info) + + # write the geoJSON and the mapper_measures.json + if not os.path.isdir(mapper_dir): + os.mkdir(mapper_dir) + with open(geojson_file, 'w') as fp: + json.dump(geojson_dict, fp, indent=4) + with open(map_meas_file, 'w') as fp: + json.dump(map_meas_list, fp, indent=4) + + +def _make_scenario(feature_geojson): + """Generate a scenario CSV file for URBANopt simulation. + + Args: + feature_geojson: The full path to a .geojson file. + """ + # load the geoJSON to a dictionary + with open(feature_geojson, 'r') as base_file: + geo_dict = json.load(base_file) + + # loop through the building features and add them to the CSV + scenario_matrix = [['Feature Id', 'Feature Name', 'Mapper Class']] + hb_mapper = 'URBANopt::Scenario::HoneybeeMapper' + for feature in geo_dict['features']: + try: + if feature['properties']['type'] == 'Building': + props = feature['properties'] + f_row = [props['id'], props['name'], hb_mapper] + scenario_matrix.append(f_row) + except KeyError: # definitely not a building + pass + + # write the scenario CSV file + uo_folder = os.path.dirname(feature_geojson) + scenario = os.path.join(uo_folder, 'honeybee_scenario.csv') + with open(scenario, 'w') as fp: + for row in scenario_matrix: + fp.write('{}\n'.format(','.join(row))) + return scenario + + +def _recommended_processor_count(): + """Get an integer for one less than the number of processors on this machine. + + This method should work on all of the major operating systems and in + both IronPython and cPython. If, for whatever reason, the number of + processors could not be sensed, a value of 1 will be returned. + """ + try: # assume that we are in cPython + cpu_count = os.cpu_count() + except AttributeError: # we are probably in IronPython + try: + from System.Environment import ProcessorCount + cpu_count = ProcessorCount + except ImportError: # no idea what Python this is; let's play it safe + cpu_count = 1 + return 1 if cpu_count is None or cpu_count <= 1 else cpu_count - 1 + + +def _run_urbanopt_windows(feature_geojson, scenario_csv): + """Run a feature and scenario file through URBANopt on a Windows-based os. + + A batch file will be used to run the simulation. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + A tuple with two values. + + - directory -- Path to the folder out of which the simulation was run. + + - stderr -- The standard error message, which should get to the user + in the event of simulation failure. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # Write the batch file to call URBANopt CLI + working_drive = directory[:2] + batch = '{}\ncd {}\ncall "{}"\nuo run -f "{}" -s "{}"'.format( + working_drive, working_drive, folders.urbanopt_env_path, + feature_geojson, scenario_csv) + batch_file = os.path.join(directory, 'run_simulation.bat') + write_to_file(batch_file, batch, True) + # run the batch file + process = subprocess.Popen( + '"{}"'.format(batch_file), stderr=subprocess.PIPE, env=PYTHON_ENV + ) + result = process.communicate() + stderr = result[1] + return directory, stderr + + +def _run_urbanopt_unix(feature_geojson, scenario_csv): + """Run a feature and scenario file through URBANopt on a Unix-based os. + + This includes both Mac OS and Linux since a shell will be used to run + the simulation. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + A tuple with two values. + + - directory -- Path to the folder out of which the simulation was run. + + - stderr -- The standard error message, which should get to the user + in the event of simulation failure. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # Write the shell script to call URBANopt CLI + shell = '#!/usr/bin/env bash\nsource "{}"\nuo run -f "{}" -s "{}"'.format( + folders.urbanopt_env_path, feature_geojson, scenario_csv) + shell_file = os.path.join(directory, 'run_simulation.sh') + write_to_file(shell_file, shell, True) + # make the shell script executable using subprocess.check_call + # this is more reliable than native Python chmod on Mac + subprocess.check_call(['chmod', 'u+x', shell_file]) + # run the shell script + process = subprocess.Popen( + '"{}"'.format(shell_file), stderr=subprocess.PIPE, env=PYTHON_ENV, shell=True + ) + result = process.communicate() + stderr = result[1] + return directory, stderr + + +def _check_urbanopt_file(feature_geojson, scenario_csv): + """Prepare an OSW file to be run through URBANopt CLI. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + The folder in which the OSW exists and out of which the OpenStudio CLI + will operate. + """ + # check the input files + assert os.path.isfile(feature_geojson), \ + 'No feature file found at {}.'.format(feature_geojson) + assert os.path.isfile(scenario_csv), \ + 'No scenario file found at {}.'.format(scenario_csv) + return os.path.split(feature_geojson)[0] + + +def _output_urbanopt_files(directory, stderr=''): + """Get the paths to the simulation output files given the urbanopt directory. + + Args: + directory: The path to where the URBANopt feature and scenario files + were simulated. + stderr: The URBANopt standard error message, which will be returned to + the user in the event that no simulation folder was found. + + Returns: + A series of file paths to the simulation output files + + - osm -- Array of paths to .osm files for all generated OpenStudio models. + + - idf -- Array of paths to .idf files containing the input for the + EnergyPlus simulation. + + - sql -- Array of paths to .sqlite files containing all simulation results. + + - zsz -- Array of paths to .csv files containing detailed zone load + information recorded over the course of the design days. + + - rdd -- Array of paths to .rdd files containing all possible outputs + that can be requested from the simulation. + + - html -- Array of paths to .htm files containing all summary reports. + + - err -- Array of paths to .err files containing all errors and + warnings from the simulation. + """ + # empty list which will be filled with simulation output files + osm = [] + idf = [] + sql = [] + zsz = [] + rdd = [] + html = [] + err = [] + + # parse the GeoJSON so that we can get the correct order of result files + sim_dir = os.path.join(directory, 'run', 'honeybee_scenario') + if not os.path.isdir(sim_dir): + msg = 'The URBANopt simulation failed to run.\n' \ + 'No results were found at:\n{}\n{}'.format(sim_dir, stderr) + print(msg) + raise Exception(msg) + geojson = [f for f in os.listdir(directory) if f.endswith('.geojson')] + if len(geojson) == 1: + geo_file = os.path.join(directory, geojson[0]) + with open(geo_file, 'r') as base_file: + geo_dict = json.load(base_file) + bldg_names = [] + for ft in geo_dict['features']: + if 'properties' in ft and 'type' in ft['properties']: + if ft['properties']['type'] == 'Building' and 'id' in ft['properties']: + bldg_names.append(ft['properties']['id']) + else: + bldg_names = os.listdir(sim_dir) + + # generate paths to the simulation files and check their existence + for bldg_name in bldg_names: + bldg_dir = os.path.join(sim_dir, bldg_name) + osm_file = os.path.join(bldg_dir, 'in.osm') + if os.path.isfile(osm_file): + osm.append(osm_file) + idf_file = os.path.join(bldg_dir, 'in.idf') + if os.path.isfile(idf_file): + idf.append(idf_file) + sql_file = os.path.join(bldg_dir, 'eplusout.sql') + if os.path.isfile(sql_file): + sql.append(sql_file) + zsz_file = os.path.join(bldg_dir, 'epluszsz.csv') + if os.path.isfile(zsz_file): + zsz.append(zsz_file) + rdd_file = os.path.join(bldg_dir, 'eplusout.rdd') + if os.path.isfile(rdd_file): + rdd.append(rdd_file) + html_file = os.path.join(bldg_dir, 'eplustbl.htm') + if os.path.isfile(html_file): + html.append(html_file) + err_file = os.path.join(bldg_dir, 'eplusout.err') + if os.path.isfile(err_file): + err.append(err_file) + + return osm, idf, sql, zsz, rdd, html, err + + +def _run_default_report_windows(feature_geojson, scenario_csv): + """Generate default reports on a Windows-based os. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + Paths to the scenario CSV and JSON reports. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # Write the batch file to call URBANopt CLI + working_drive = directory[:2] + batch = '{}\ncd {}\ncall "{}"\nuo process --default -f "{}" -s "{}"'.format( + working_drive, working_drive, folders.urbanopt_env_path, + feature_geojson, scenario_csv) + batch_file = os.path.join(directory, 'run_default_report.bat') + write_to_file(batch_file, batch, True) + # run the batch file and return output files + os.system('"{}"'.format(batch_file)) + result_folder = os.path.basename(scenario_csv).lower().replace('.csv', '') + run_folder = os.path.join(directory, 'run', result_folder) + return os.path.join(run_folder, 'default_scenario_report.csv'), \ + os.path.join(run_folder, 'default_scenario_report.json') + + +def _run_default_report_unix(feature_geojson, scenario_csv): + """Generate default reports on a Unix-based os. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + Paths to the scenario CSV and JSON reports. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # Write the shell script to call OpenStudio CLI + shell = '#!/usr/bin/env bash\nsource "{}"\n' \ + 'uo process --default -f "{}" -s "{}"'.format( + folders.urbanopt_env_path, feature_geojson, scenario_csv) + shell_file = os.path.join(directory, 'run_default_report.sh') + write_to_file(shell_file, shell, True) + # make the shell script executable using subprocess.check_call + # this is more reliable than native Python chmod on Mac + subprocess.check_call(['chmod', 'u+x', shell_file]) + # run the shell script + subprocess.call(shell_file) + result_folder = os.path.basename(scenario_csv).lower().replace('.csv', '') + run_folder = os.path.join(directory, 'run', result_folder) + return os.path.join(run_folder, 'default_scenario_report.csv'), \ + os.path.join(run_folder, 'default_scenario_report.json') + + +def _run_reopt_windows(feature_geojson, scenario_csv, developer_key): + """Run a feature and scenario file through REopt on a Windows-based os. + + A batch file will be used to run the simulation. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + developer_key: Text string for the NREL developer key. + + Returns: + Path to the folder in which results should be contained. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # Write the batch file to call URBANopt CLI + working_drive = directory[:2] + batch = '{}\ncd {}\ncall "{}"\nSET GEM_DEVELOPER_KEY={}\n' \ + 'uo process --reopt-scenario -f "{}" -s "{}"'.format( + working_drive, working_drive, folders.urbanopt_env_path, developer_key, + feature_geojson, scenario_csv) + batch_file = os.path.join(directory, 'run_reopt.bat') + write_to_file(batch_file, batch, True) + # run the batch file + os.system('"{}"'.format(batch_file)) + result_folder = os.path.basename(scenario_csv).lower().replace('.csv', '') + return os.path.join(directory, 'run', result_folder) + + +def _run_reopt_unix(feature_geojson, scenario_csv, developer_key): + """Run a feature and scenario file through REopt on a Unix-based os. + + This includes both Mac OS and Linux since a shell will be used to run + the simulation. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + developer_key: Text string for the NREL developer key. + + Returns: + Path to the folder in which results should be contained. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # Write the shell script to call OpenStudio CLI + shell = '#!/usr/bin/env bash\nsource "{}"\nGEM_DEVELOPER_KEY={}\n' \ + 'uo process --reopt-scenario -f "{}" -s "{}"'.format( + folders.urbanopt_env_path, developer_key, feature_geojson, scenario_csv) + shell_file = os.path.join(directory, 'run_reopt.sh') + write_to_file(shell_file, shell, True) + # make the shell script executable using subprocess.check_call + # this is more reliable than native Python chmod on Mac + subprocess.check_call(['chmod', 'u+x', shell_file]) + # run the shell script + subprocess.call(shell_file) + result_folder = os.path.basename(scenario_csv).lower().replace('.csv', '') + return os.path.join(directory, 'run', result_folder) + + +def _output_reopt_files(directory): + """Get the paths to the simulation output files given the reopt directory. + + Args: + directory: The path to the folder in which results should be contained. + + Returns: + A series of file paths to the simulation output files + + - csv -- Path to a CSV file containing scenario optimization results. + + - report_json -- Path to a JSON file containing scenario optimization results. + """ + # generate paths to the simulation files + csv_file = os.path.join(directory, 'scenario_optimization.csv') + report_json_file = os.path.join(directory, 'scenario_optimization.json') + # check that the simulation files exist + csv = csv_file if os.path.isfile(csv_file) else None + report_json = report_json_file if os.path.isfile(report_json_file) else None + return csv, report_json + + +def _run_rnm_windows(feature_geojson, scenario_csv): + """Run a feature and scenario file through RNM on a Windows-based os. + + A batch file will be used to run the simulation. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + Path to the project folder. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # Write the batch file to call URBANopt CLI + working_drive = directory[:2] + batch = '{}\ncd {}\ncall "{}"\nuo rnm --feature "{}" --scenario "{}"'.format( + working_drive, working_drive, folders.urbanopt_env_path, + feature_geojson, scenario_csv) + batch_file = os.path.join(directory, 'run_rnm.bat') + write_to_file(batch_file, batch, True) + # run the batch file + os.system('"{}"'.format(batch_file)) + return directory + + +def _run_rnm_unix(feature_geojson, scenario_csv): + """Run a feature and scenario file through RNM on a Unix-based os. + + This includes both Mac OS and Linux since a shell script will be used to run + the simulation. + + Args: + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + Path to the project folder. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # Write the shell script to call URBANopt CLI + shell = '#!/usr/bin/env bash\nsource "{}"\nuo rnm --feature "{}" -s-scenario ' \ + '"{}"'.format(folders.urbanopt_env_path, feature_geojson, scenario_csv) + shell_file = os.path.join(directory, 'run_rnm.sh') + write_to_file(shell_file, shell, True) + # make the shell script executable using subprocess.check_call + # this is more reliable than native Python chmod on Mac + subprocess.check_call(['chmod', 'u+x', shell_file]) + # run the shell script + subprocess.call(shell_file) + return directory + + +def _generate_modelica_windows(sys_param_json, feature_geojson, scenario_csv): + """Generate Modelica files for a DES on a Windows-based os. + + A batch file will be used to run the simulation. + + Args: + sys_param_json: The full path to a system parameter JSON from which the + Modelica files will be generated. + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + A tuple with two values. + + - modelica_dir -- Path to the folder in which the Modelica files were written. + + - stderr -- The standard error message, which should get to the user + in the event of simulation failure. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # get the path to the MBL installation + install_directory = os.path.join(lb_folders.ladybug_tools_folder, 'resources') + mbl_dir = os.path.join(install_directory, 'mbl') + assert os.path.isdir(mbl_dir), \ + 'No Modelica Buildings Library installation was found on this machine.' + # get the paths to the output files + scn_name = os.path.basename(scenario_csv).replace('.csv', '') + modelica_dir = os.path.join(directory, 'run', scn_name, 'des_modelica') + uo_des_exe = os.path.join(hb_folders.python_scripts_path, 'uo_des.exe') + # Write the batch file to call the GMT + working_drive = directory[:2] + batch = '{}\ncd {}\ncall "{}"\nSET "MODELICAPATH={}"\n"{}" create-model ' \ + '"{}" "{}" "{}" --overwrite'.format( + working_drive, working_drive, folders.urbanopt_env_path, mbl_dir, + uo_des_exe, sys_param_json, feature_geojson, modelica_dir) + batch_file = os.path.join(directory, 'generate_modelica.bat') + write_to_file(batch_file, batch, True) + # run the batch file + process = subprocess.Popen( + '"{}"'.format(batch_file), stderr=subprocess.PIPE, env=PYTHON_ENV + ) + result = process.communicate() + stderr = result[1] + return modelica_dir, stderr + + +def _generate_modelica_unix(sys_param_json, feature_geojson, scenario_csv): + """Generate Modelica files for a DES on a Unix-based os. + + This includes both Mac OS and Linux since a shell will be used to run + the simulation. + + Args: + sys_param_json: The full path to a system parameter JSON from which the + Modelica files will be generated. + feature_geojson: The full path to a .geojson file containing the + footprints of buildings to be simulated. + scenario_csv: The full path to a .csv file for the URBANopt scenario. + + Returns: + A tuple with two values. + + - directory -- Path to the folder out of which the simulation was run. + + - stderr -- The standard error message, which should get to the user + in the event of simulation failure. + """ + # check the input file + directory = _check_urbanopt_file(feature_geojson, scenario_csv) + # get the path to the MBL installation + install_directory = os.path.join(lb_folders.ladybug_tools_folder, 'resources') + mbl_dir = os.path.join(install_directory, 'mbl') + assert os.path.isdir(mbl_dir), \ + 'No Modelica Buildings Library installation was found on this machine.' + # get the paths to the output files + scn_name = os.path.basename(scenario_csv).replace('.csv', '') + modelica_dir = os.path.join(directory, 'run', scn_name, 'des_modelica') + uo_des_exe = os.path.join(hb_folders.python_scripts_path, 'uo_des') + # write the shell script to call the GMT + shell = '#!/usr/bin/env bash\nsource "{}"\nexport MODELICAPATH="{}"\n' \ + '"{}" create-model "{}" "{}" "{}" --overwrite'.format( + folders.urbanopt_env_path, mbl_dir, + uo_des_exe, sys_param_json, feature_geojson, modelica_dir) + shell_file = os.path.join(directory, 'generate_modelica.sh') + write_to_file(shell_file, shell, True) + # make the shell script executable using subprocess.check_call + # this is more reliable than native Python chmod on Mac + subprocess.check_call(['chmod', 'u+x', shell_file]) + # run the shell script + process = subprocess.Popen( + '"{}"'.format(shell_file), stderr=subprocess.PIPE, env=PYTHON_ENV, shell=True + ) + result = process.communicate() + stderr = result[1] + return modelica_dir, stderr + + +def _add_water_heating_patch(modelica_dir): + """Add a dummy value for water heating for MBL 10 limitation.""" + data_dir = os.path.join(modelica_dir, 'Loads', 'Resources', 'Data') + if os.path.isdir(data_dir): + for bldg_dir in os.listdir(data_dir): + mo_load_file = os.path.join(data_dir, bldg_dir, 'modelica.mos') + if os.path.isfile(mo_load_file): + fixed_lines, fl_found = [], False + with open(mo_load_file, 'r') as mlf: + for line in mlf: + if line == '#Peak water heating load = 0 Watts\n': + nl = '#Peak water heating load = 1 Watts\n' + fixed_lines.append(nl) + elif not fl_found and ';' in line: + split_vals = line.split(';') + split_vals[-1] = '1.0\n' + fixed_lines.append(';'.join(split_vals)) + fl_found = True + else: + fixed_lines.append(line) + with open(mo_load_file, 'w') as mlf: + mlf.write(''.join(fixed_lines)) + + +def _run_modelica_windows(modelica_project_dir): + """Execute Modelica files of a DES on a Windows-based OS. + + A batch file will be used to run the simulation. + + Args: + modelica_project_dir: The full path to the folder in which the Modelica + files were written. + + Returns: + A tuple with two values. + + - results -- Path to where the results were written. + + - stderr -- The standard error message, which should get to the user + in the event of simulation failure. + """ + # make sure that docker is installed + assert folders.docker_version_str is not None, \ + 'No Docker installation was found on this machine.\n' \ + 'This is needed to execute Modelica simulations.' + # get the paths to the output files + directory = os.path.dirname(modelica_project_dir) + project_name = os.path.basename(modelica_project_dir) + results = os.path.join( + modelica_project_dir, + '{}.Districts.DistrictEnergySystem_results'.format(project_name)) + uo_des_exe = os.path.join(hb_folders.python_scripts_path, 'uo_des.exe') + # Write the batch file to call the GMT + working_drive = modelica_project_dir[:2] + batch = '{}\ncd {}\n"{}" run-model "{}"'.format( + working_drive, working_drive, uo_des_exe, modelica_project_dir) + batch_file = os.path.join(directory, 'run_modelica.bat') + write_to_file(batch_file, batch, True) + # run the batch file + process = subprocess.Popen( + '"{}"'.format(batch_file), stderr=subprocess.PIPE, env=PYTHON_ENV + ) + result = process.communicate() + stderr = result[1] + return results, stderr + + +def _run_modelica_unix(modelica_project_dir): + """Execute Modelica files of a DES on a Unix-based OS. + + This includes both Mac OS and Linux since a shell will be used to run + the simulation. + + Args: + modelica_project_dir: The full path to the folder in which the Modelica + files were written. + + Returns: + A tuple with two values. + + - results -- Path to where the results were written. + + - stderr -- The standard error message, which should get to the user + in the event of simulation failure. + """ + # make sure that docker is installed + assert folders.docker_version_str is not None, \ + 'No Docker installation was found on this machine.\n' \ + 'This is needed to execute Modelica simulations.' + # get the paths to the output files + directory = os.path.dirname(modelica_project_dir) + project_name = os.path.basename(modelica_project_dir) + results = os.path.join( + modelica_project_dir, + '{}.Districts.DistrictEnergySystem_results'.format(project_name)) + uo_des_exe = os.path.join(hb_folders.python_scripts_path, 'uo_des') + # write the shell script to call the GMT + shell = '#!/usr/bin/env bash\n"{}" run-model "{}"'.format( + uo_des_exe, modelica_project_dir) + shell_file = os.path.join(directory, 'run_modelica.sh') + write_to_file(shell_file, shell, True) + # make the shell script executable using subprocess.check_call + # this is more reliable than native Python chmod on Mac + subprocess.check_call(['chmod', 'u+x', shell_file]) + # run the shell script + process = subprocess.Popen( + '"{}"'.format(shell_file), stderr=subprocess.PIPE, env=PYTHON_ENV, shell=True + ) + result = process.communicate() + stderr = result[1] + return results, stderr +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/dragonfly_energy/writer.html b/docs/_modules/dragonfly_energy/writer.html new file mode 100644 index 00000000..35428a7a --- /dev/null +++ b/docs/_modules/dragonfly_energy/writer.html @@ -0,0 +1,1357 @@ + + + + + + + dragonfly_energy.writer — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    + +

    Source code for dragonfly_energy.writer

    +# coding=utf-8
    +"""Methods to write files for URBANopt simulation from a Model."""
    +import sys
    +import os
    +import re
    +import json
    +import shutil
    +
    +from ladybug_geometry.geometry2d import Point2D
    +from ladybug.futil import nukedir, preparedir
    +from ladybug.epw import EPW
    +from honeybee.config import folders
    +from honeybee.model import Model as hb_model
    +
    +
    +
    +[docs] +def model_to_urbanopt( + model, location, point=Point2D(0, 0), shade_distance=None, use_multiplier=True, + add_plenum=False, solve_ceiling_adjacencies=False, + des_loop=None, electrical_network=None, road_network=None, ground_pv=None, + folder=None, tolerance=None +): + r"""Generate an URBANopt feature geoJSON and honeybee JSONs from a dragonfly Model. + + Args: + model: A dragonfly Model for which an URBANopt feature geoJSON and + corresponding honeybee Model JSONs will be returned. + location: A ladybug Location object possessing longitude and latitude data. + point: A ladybug_geometry Point2D for where the location object exists + within the space of a scene. The coordinates of this point are + expected to be in the units of this Model. (Default: (0, 0)). + shade_distance: An optional number to note the distance beyond which other + objects' shade should not be exported into a given honeybee Model. This + is helpful for reducing the simulation run time of each Model when other + connected buildings are too far away to have a meaningful impact on + the results. If None, all other buildings will be included as context + shade in each and every Model. Set to 0 to exclude all neighboring + buildings from the resulting models. (Default: None). + use_multiplier: If True, the multipliers on the Model's Stories will be + passed along to the generated Honeybee Room objects, indicating the + simulation will be run once for each unique room and then results + will be multiplied. If False, full geometry objects will be written + for each and every floor in the building that are represented through + multipliers and all resulting multipliers will be 1. (Default: True). + add_plenum: Boolean to indicate whether ceiling/floor plenums should + be auto-generated for the Rooms. (Default: False). + solve_ceiling_adjacencies: Boolean to note whether adjacencies should be + solved between interior stories when Room2Ds perfectly match one + another in their floor plate. This ensures that Surface boundary + conditions are used instead of Adiabatic ones. Note that this input + has no effect when the object_per_model is Story. (Default: False). + des_loop: An optional District Energy System (DES) ThermalLoop that's + associated with the dragonfly Model. (Default: None). + electrical_network: An optional OpenDSS ElectricalNetwork that's associated + with the dragonfly Model. (Default: None). + road_network: An optional RNM RoadNetwork that's associated with the + dragonfly Model. (Default: None). + ground_pv: An optional list of REopt GroundMountPV objects representing + ground-mounted photovoltaic fields to be included in the REopt + simulation. (Default: None). + folder: An optional folder to be used as the root of the model's + URBANopt folder. If None, the files will be written into a sub-directory + of the honeybee-core default_simulation_folder. + tolerance: The minimum distance between points at which they are + not considered touching. If None, the Model tolerance will be used. + + Returns: + A tuple with three values. + + feature_geojson -- The path to an URBANopt feature geoJSON that has + been written by this method. + + hb_model_jsons -- An array of file paths to honeybee Model JSONs that + correspond to the detailed_model_filename keys in the feature_geojson. + + hb_models -- An array of honeybee Model objects that were generated in + process of writing the URBANopt files. + """ + # make sure the model is in meters and, if it's not, duplicate and scale it + conversion_factor, original_units = None, 'Meters' + tolerance = model.tolerance if tolerance is None else tolerance + if model.units != 'Meters': + original_units = model.units + conversion_factor = hb_model.conversion_factor_to_meters(model.units) + point = point.scale(conversion_factor) + if shade_distance is not None: + shade_distance = shade_distance * conversion_factor + tolerance = tolerance * conversion_factor + model = model.duplicate() # duplicate the model to avoid mutating the input + model.convert_to_units('Meters') + if des_loop is not None: + des_loop.scale(conversion_factor) + if electrical_network is not None: + electrical_network.scale(conversion_factor) + if road_network is not None: + road_network.scale(conversion_factor) + if ground_pv is not None: + for g_pv in ground_pv: + g_pv.scale(conversion_factor) + + # prepare the folder for simulation + tr_msg = 'The following simulation folder is too long to be used with URBANopt:' \ + '\n{}\nSpecify a shorter folder path in which to write the GeoJSON.' + if folder is None: # use the default simulation folder + assert len(folders.default_simulation_folder) < 55, \ + tr_msg.format(folders.default_simulation_folder) + sim_dir = re.sub(r'[^.A-Za-z0-9_-]', '_', model.display_name) + folder = os.path.join(folders.default_simulation_folder, sim_dir) + if len(folder) >= 60: + tr_len = 58 - len(folders.default_simulation_folder) + folder = os.path.join(folders.default_simulation_folder, sim_dir[:tr_len]) + else: + assert len(folder) < 60, tr_msg.format(folder) + + # get rid of all simulation files that exists in the folder already + dir_to_delete = ('hb_json', 'mappers', 'run') + ext_to_delete = ('.bat', '.geojson', '.epw', '.mos') + file_to_delete = ( + 'Gemfile', 'Gemfile.lock', 'honeybee_scenario.csv', 'runner.conf', + 'simulation_parameter.json', 'system_params.json', + 'electrical_database.json', 'network.json' + ) + if os.path.isdir(folder): + files = os.listdir(folder) + for f in files: + path = os.path.join(folder, f) + if os.path.isdir(path): + if f in dir_to_delete: + nukedir(path, True) + else: + if f in file_to_delete: + os.remove(path) + elif f.endswith(ext_to_delete): + os.remove(path) + else: + preparedir(folder) # create the directory if it's not there + + # prepare the folder into which honeybee Model JSONs will be written + hb_model_folder = os.path.join(folder, 'hb_json') # folder for honeybee JSONs + preparedir(hb_model_folder) + + # create GeoJSON dictionary + geojson_dict = model.to_geojson_dict(location, point, tolerance=tolerance) + for feature_dict in geojson_dict['features']: # add the detailed model filename + if feature_dict['properties']['type'] == 'Building': + bldg_id = feature_dict['properties']['id'] + feature_dict['properties']['detailed_model_filename'] = \ + os.path.join(hb_model_folder, '{}.json'.format(bldg_id)) + + # add the DES to the GeoJSON dictionary + if des_loop is not None: + if hasattr(des_loop, 'to_geojson_dict'): + des_features = des_loop.to_geojson_dict( + model.buildings, location, point, tolerance=tolerance) + geojson_dict['features'].extend(des_features) + sys_p_json = os.path.join(folder, 'system_params.json') + with open(sys_p_json, 'w') as fp: + des_dict = des_loop.to_des_param_dict(model.buildings, tolerance=tolerance) + json.dump(des_dict, fp, indent=2) + if conversion_factor is not None: + des_loop.scale(1 / conversion_factor) + + # add the electrical network to the GeoJSON dictionary + if electrical_network is not None: + electric_features = electrical_network.to_geojson_dict( + model.buildings, location, point, tolerance=tolerance) + geojson_dict['features'].extend(electric_features) + electric_json = os.path.join(folder, 'electrical_database.json') + with open(electric_json, 'w') as fp: + json.dump(electrical_network.to_electrical_database_dict(), fp, indent=4) + if conversion_factor is not None: + electrical_network.scale(1 / conversion_factor) + + # add the road network to the GeoJSON dictionary + if road_network is not None: + road_features = road_network.to_geojson_dict(location, point) + geojson_dict['features'].extend(road_features) + if conversion_factor is not None: + road_network.scale(1 / conversion_factor) + + # add the ground-mounted PV to the GeoJSON dictionary + if ground_pv is not None and len(ground_pv) != 0: + pv_features = [g_pv.to_geojson_dict(location, point) for g_pv in ground_pv] + geojson_dict['features'].extend(pv_features) + if conversion_factor is not None: + for g_pv in ground_pv: + g_pv.scale(1 / conversion_factor) + + # write out the GeoJSON file + feature_geojson = os.path.join(folder, '{}.geojson'.format(model.identifier)) + if (sys.version_info < (3, 0)): # we need to manually encode it as UTF-8 + with open(feature_geojson, 'wb') as fp: + obj_str = json.dumps(geojson_dict, indent=4, ensure_ascii=False) + fp.write(obj_str.encode('utf-8')) + else: + with open(feature_geojson, 'w', encoding='utf-8') as fp: + obj_str = json.dump(geojson_dict, fp, indent=4, ensure_ascii=False) + + # write out the honeybee Model JSONs from the model + hb_model_jsons = [] + hb_models = model.to_honeybee( + 'Building', shade_distance, use_multiplier, add_plenum, + solve_ceiling_adjacencies=solve_ceiling_adjacencies, tolerance=tolerance) + for bldg_model in hb_models: + try: + bldg_model.remove_degenerate_geometry(0.01) + except ValueError: + error = 'Failed to remove degenerate Geometry.\nYour Model units system is: {}. ' \ + 'Is this correct?'.format(original_units) + raise ValueError(error) + model_dict = bldg_model.to_dict(triangulate_sub_faces=True) + bldg_model.properties.energy.add_autocal_properties_to_dict(model_dict) + bld_path = os.path.join(hb_model_folder, '{}.json'.format(bldg_model.identifier)) + if (sys.version_info < (3, 0)): # we need to manually encode it as UTF-8 + with open(bld_path, 'wb') as fp: + obj_str = json.dumps(model_dict, indent=4, ensure_ascii=False) + fp.write(obj_str.encode('utf-8')) + else: + with open(bld_path, 'w', encoding='utf-8') as fp: + obj_str = json.dump(model_dict, fp, indent=4, ensure_ascii=False) + hb_model_jsons.append(bld_path) + + return feature_geojson, hb_model_jsons, hb_models
    + + + +
    +[docs] +def model_to_des( + model, des_loop, epw_file, location=None, point=Point2D(0, 0), + folder=None, tolerance=None +): + r"""Generate an URBANopt feature geoJSON and DES input files from a dragonfly Model. + + This method is intended specifically for the case that District Energy + System (DES) simulation is to be performed without using URBANopt to generate + building energy loads through EnergyPlus. Accordingly, ALL Dragonfly Buildings + in the Model must have DES loads assigned directly to them in order for this + method to run correctly. + + Args: + model: A dragonfly Model for which an URBANopt feature geoJSON and + corresponding DES input files will be generated. + des_loop: A District Energy System (DES) ThermalLoop that is associated + with the dragonfly Model. + epw_file: The file path to an EPW that should be associated with the + output energy model. + location: An optional ladybug Location object possessing longitude and + latitude data. If None, the Location data will be pulled from the + input epw_file, effectively placing the GeoJSON at the location + of the EPW + point: A ladybug_geometry Point2D for where the location object exists + within the space of a scene. The coordinates of this point are + expected to be in the units of this Model. (Default: (0, 0)). + folder: An optional folder to be used as the root of the model's + URBANopt folder. If None, the files will be written into a sub-directory + of the honeybee-core default_simulation_folder. + tolerance: The minimum distance between points at which they are + not considered touching. If None, the Model tolerance will be used. + + Returns: + A tuple with three values. + + feature_geojson -- The path to an URBANopt feature geoJSON that has + been written by this method. + + scenario_csv -- The path to an URBANopt scenario CSV that has + been written by this method. + + system_parameters -- The path to the DES system parameter JSON that has + been written by this method. + """ + # make sure the model is in meters and, if it's not, duplicate and scale it + conversion_factor = None + tolerance = model.tolerance if tolerance is None else tolerance + if model.units != 'Meters': + conversion_factor = hb_model.conversion_factor_to_meters(model.units) + point = point.scale(conversion_factor) + tolerance = tolerance * conversion_factor + model = model.duplicate() # duplicate the model to avoid mutating the input + model.convert_to_units('Meters') + des_loop.scale(conversion_factor) + + # prepare the folder for simulation + if folder is None: # use the default simulation folder + folder = os.path.join( + folders.default_simulation_folder, + re.sub(r'[^.A-Za-z0-9_-]', '_', model.display_name) + ) + nukedir(folder, True) # get rid of anything that exists in the folder already + preparedir(folder) # create the directory if it's not there + + # create GeoJSON dictionary + epw_obj = EPW(epw_file) + if location is None: + location = epw_obj.location + geojson_dict = model.to_geojson_dict(location, point, tolerance=tolerance) + + # create the scenario CSV file + scenario_matrix = [['Feature Id', 'Feature Name', 'Mapper Class']] + hb_mapper = 'URBANopt::Scenario::HoneybeeMapper' + for feature in geojson_dict['features']: + try: + if feature['properties']['type'] == 'Building': + props = feature['properties'] + f_row = [props['id'], props['name'], hb_mapper] + scenario_matrix.append(f_row) + except KeyError: # definitely not a building + pass + scenario_csv = os.path.join(folder, 'honeybee_scenario.csv') + with open(scenario_csv, 'w') as fp: + for row in scenario_matrix: + fp.write('{}\n'.format(','.join(row))) + + # write the Building loads into the scenario result folder + scn_dir = os.path.join(folder, 'run', 'honeybee_scenario') + for bldg in model.buildings: + csv_data = bldg.properties.energy.to_building_load_csv() + mos_data = bldg.properties.energy.to_building_load_mos() + bldg_dir = os.path.join(scn_dir, bldg.identifier, '004_export_modelica_loads') + preparedir(bldg_dir) + csv_path = os.path.join(bldg_dir, 'building_loads.csv') + mos_path = os.path.join(bldg_dir, 'modelica.mos') + with open(csv_path, 'w') as fp: + fp.write(csv_data) + with open(mos_path, 'w') as fp: + fp.write(mos_data) + + # add the DES to the GeoJSON dictionary + if hasattr(des_loop, 'to_geojson_dict'): + des_features = des_loop.to_geojson_dict( + model.buildings, location, point, tolerance=tolerance) + geojson_dict['features'].extend(des_features) + des_dict = des_loop.to_des_param_dict(model.buildings, tolerance=tolerance) + if conversion_factor is not None: # put back the correct scale for the DES + des_loop.scale(1 / conversion_factor) + + # copy the EPW to the project directory + epw_f_name = os.path.split(epw_file)[-1] + target_epw = os.path.join(folder, epw_f_name) + shutil.copy(epw_file, target_epw) + # create a MOS file from the EPW + epw_obj = EPW(target_epw) + mos_file = os.path.join(folder, epw_f_name.replace('.epw', '.mos')) + epw_obj.to_mos(mos_file) + # write the EPW path into the GeoJSON + if 'project' in geojson_dict: + if 'weather_filename' not in geojson_dict['project']: + geojson_dict['project']['weather_filename'] = epw_f_name + + # if the DES system is GSHP, specify any autocalculated ground temperatures + if 'district_system' in des_dict: + if 'fifth_generation' in des_dict['district_system']: + g5_par = des_dict['district_system']['fifth_generation'] + if 'soil' in g5_par and 'undisturbed_temp' in g5_par['soil']: + soil_par = g5_par['soil'] + if soil_par['undisturbed_temp'] == 'Autocalculate': + epw_obj = EPW(epw_file) + soil_par['undisturbed_temp'] = \ + epw_obj.dry_bulb_temperature.average + + # write out the GeoJSON and system parameter files + feature_geojson = os.path.join(folder, '{}.geojson'.format(model.identifier)) + system_parameters = os.path.join(folder, 'system_params.json') + if (sys.version_info < (3, 0)): # we need to manually encode it as UTF-8 + with open(feature_geojson, 'wb') as fp: + obj_str = json.dumps(geojson_dict, indent=4, ensure_ascii=False) + fp.write(obj_str.encode('utf-8')) + with open(system_parameters, 'wb') as fp: + obj_str = json.dumps(des_dict, indent=2, ensure_ascii=False) + fp.write(obj_str.encode('utf-8')) + else: + with open(feature_geojson, 'w', encoding='utf-8') as fp: + obj_str = json.dump(geojson_dict, fp, indent=4, ensure_ascii=False) + with open(system_parameters, 'w') as fp: + json.dump(des_dict, fp, indent=2) + + return feature_geojson, scenario_csv, system_parameters
    + +
    + +
    + +
    +
    +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_modules/index.html b/docs/_modules/index.html new file mode 100644 index 00000000..7acee09e --- /dev/null +++ b/docs/_modules/index.html @@ -0,0 +1,1006 @@ + + + + + + + Overview: module code — dragonfly-energy documentation + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +

    + Back to top + +

    +

    + © Copyright 2024, Ladybug Tools.
    + Created using Sphinx 8.0.2.
    +

    +
    +
    + + \ No newline at end of file diff --git a/docs/_sources/cli/index.rst.txt b/docs/_sources/cli/index.rst.txt new file mode 100644 index 00000000..e2544a14 --- /dev/null +++ b/docs/_sources/cli/index.rst.txt @@ -0,0 +1,16 @@ +CLI Docs +======== + +Installation +------------ + +To check if the command line is installed correctly use ``dragonfly-energy --help`` + +Commands +-------- +.. toctree:: + :maxdepth: 1 + + translate + install + simulate diff --git a/docs/_sources/cli/install.rst.txt b/docs/_sources/cli/install.rst.txt new file mode 100644 index 00000000..7edf3270 --- /dev/null +++ b/docs/_sources/cli/install.rst.txt @@ -0,0 +1,6 @@ +install +======= + +.. click:: dragonfly_energy.cli.install:install + :prog: dragonfly-energy install + :show-nested: diff --git a/docs/_sources/cli/simulate.rst.txt b/docs/_sources/cli/simulate.rst.txt new file mode 100644 index 00000000..8407287b --- /dev/null +++ b/docs/_sources/cli/simulate.rst.txt @@ -0,0 +1,6 @@ +simulate +======== + +.. click:: dragonfly_energy.cli.simulate:simulate + :prog: dragonfly-energy simulate + :show-nested: diff --git a/docs/_sources/cli/translate.rst.txt b/docs/_sources/cli/translate.rst.txt new file mode 100644 index 00000000..60746e07 --- /dev/null +++ b/docs/_sources/cli/translate.rst.txt @@ -0,0 +1,6 @@ +translate +========= + +.. click:: dragonfly_energy.cli.translate:translate + :prog: dragonfly-energy translate + :show-nested: diff --git a/docs/_sources/dragonfly_energy.cli.install.rst.txt b/docs/_sources/dragonfly_energy.cli.install.rst.txt new file mode 100644 index 00000000..c882e208 --- /dev/null +++ b/docs/_sources/dragonfly_energy.cli.install.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.cli.install module +==================================== + +.. automodule:: dragonfly_energy.cli.install + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.cli.rst.txt b/docs/_sources/dragonfly_energy.cli.rst.txt new file mode 100644 index 00000000..98b0008f --- /dev/null +++ b/docs/_sources/dragonfly_energy.cli.rst.txt @@ -0,0 +1,20 @@ +dragonfly\_energy.cli package +============================= + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy.cli.install + dragonfly_energy.cli.simulate + dragonfly_energy.cli.translate + +Module contents +--------------- + +.. automodule:: dragonfly_energy.cli + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.cli.simulate.rst.txt b/docs/_sources/dragonfly_energy.cli.simulate.rst.txt new file mode 100644 index 00000000..80f795d0 --- /dev/null +++ b/docs/_sources/dragonfly_energy.cli.simulate.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.cli.simulate module +===================================== + +.. automodule:: dragonfly_energy.cli.simulate + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.cli.translate.rst.txt b/docs/_sources/dragonfly_energy.cli.translate.rst.txt new file mode 100644 index 00000000..c0393d4a --- /dev/null +++ b/docs/_sources/dragonfly_energy.cli.translate.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.cli.translate module +====================================== + +.. automodule:: dragonfly_energy.cli.translate + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.config.rst.txt b/docs/_sources/dragonfly_energy.config.rst.txt new file mode 100644 index 00000000..4fb5bf7f --- /dev/null +++ b/docs/_sources/dragonfly_energy.config.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.config module +=============================== + +.. automodule:: dragonfly_energy.config + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.des.connector.rst.txt b/docs/_sources/dragonfly_energy.des.connector.rst.txt new file mode 100644 index 00000000..2d8b6406 --- /dev/null +++ b/docs/_sources/dragonfly_energy.des.connector.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.des.connector module +====================================== + +.. automodule:: dragonfly_energy.des.connector + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.des.ghe.rst.txt b/docs/_sources/dragonfly_energy.des.ghe.rst.txt new file mode 100644 index 00000000..491c1da4 --- /dev/null +++ b/docs/_sources/dragonfly_energy.des.ghe.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.des.ghe module +================================ + +.. automodule:: dragonfly_energy.des.ghe + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.des.junction.rst.txt b/docs/_sources/dragonfly_energy.des.junction.rst.txt new file mode 100644 index 00000000..50b43c40 --- /dev/null +++ b/docs/_sources/dragonfly_energy.des.junction.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.des.junction module +===================================== + +.. automodule:: dragonfly_energy.des.junction + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.des.loop.rst.txt b/docs/_sources/dragonfly_energy.des.loop.rst.txt new file mode 100644 index 00000000..ee554e3a --- /dev/null +++ b/docs/_sources/dragonfly_energy.des.loop.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.des.loop module +================================= + +.. automodule:: dragonfly_energy.des.loop + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.des.rst.txt b/docs/_sources/dragonfly_energy.des.rst.txt new file mode 100644 index 00000000..afbc82a2 --- /dev/null +++ b/docs/_sources/dragonfly_energy.des.rst.txt @@ -0,0 +1,21 @@ +dragonfly\_energy.des package +============================= + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy.des.connector + dragonfly_energy.des.ghe + dragonfly_energy.des.junction + dragonfly_energy.des.loop + +Module contents +--------------- + +.. automodule:: dragonfly_energy.des + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.measure.rst.txt b/docs/_sources/dragonfly_energy.measure.rst.txt new file mode 100644 index 00000000..75920b75 --- /dev/null +++ b/docs/_sources/dragonfly_energy.measure.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.measure module +================================ + +.. automodule:: dragonfly_energy.measure + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.colorobj.rst.txt b/docs/_sources/dragonfly_energy.opendss.colorobj.rst.txt new file mode 100644 index 00000000..8bafc496 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.colorobj.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.colorobj module +========================================= + +.. automodule:: dragonfly_energy.opendss.colorobj + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.connector.rst.txt b/docs/_sources/dragonfly_energy.opendss.connector.rst.txt new file mode 100644 index 00000000..f319b1a2 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.connector.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.connector module +========================================== + +.. automodule:: dragonfly_energy.opendss.connector + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.junction.rst.txt b/docs/_sources/dragonfly_energy.opendss.junction.rst.txt new file mode 100644 index 00000000..c17e23d9 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.junction.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.junction module +========================================= + +.. automodule:: dragonfly_energy.opendss.junction + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.lib.powerlines.rst.txt b/docs/_sources/dragonfly_energy.opendss.lib.powerlines.rst.txt new file mode 100644 index 00000000..4a33954a --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.lib.powerlines.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.lib.powerlines module +=============================================== + +.. automodule:: dragonfly_energy.opendss.lib.powerlines + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.lib.rst.txt b/docs/_sources/dragonfly_energy.opendss.lib.rst.txt new file mode 100644 index 00000000..3900a9e5 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.lib.rst.txt @@ -0,0 +1,20 @@ +dragonfly\_energy.opendss.lib package +===================================== + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy.opendss.lib.powerlines + dragonfly_energy.opendss.lib.transformers + dragonfly_energy.opendss.lib.wires + +Module contents +--------------- + +.. automodule:: dragonfly_energy.opendss.lib + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.lib.transformers.rst.txt b/docs/_sources/dragonfly_energy.opendss.lib.transformers.rst.txt new file mode 100644 index 00000000..5f53fc7a --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.lib.transformers.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.lib.transformers module +================================================= + +.. automodule:: dragonfly_energy.opendss.lib.transformers + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.lib.wires.rst.txt b/docs/_sources/dragonfly_energy.opendss.lib.wires.rst.txt new file mode 100644 index 00000000..2050a013 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.lib.wires.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.lib.wires module +========================================== + +.. automodule:: dragonfly_energy.opendss.lib.wires + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.network.rst.txt b/docs/_sources/dragonfly_energy.opendss.network.rst.txt new file mode 100644 index 00000000..4a4e4c3c --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.network.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.network module +======================================== + +.. automodule:: dragonfly_energy.opendss.network + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.powerline.rst.txt b/docs/_sources/dragonfly_energy.opendss.powerline.rst.txt new file mode 100644 index 00000000..72bb97bd --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.powerline.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.powerline module +========================================== + +.. automodule:: dragonfly_energy.opendss.powerline + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.result.rst.txt b/docs/_sources/dragonfly_energy.opendss.result.rst.txt new file mode 100644 index 00000000..0d05391a --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.result.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.result module +======================================= + +.. automodule:: dragonfly_energy.opendss.result + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.road.rst.txt b/docs/_sources/dragonfly_energy.opendss.road.rst.txt new file mode 100644 index 00000000..cfdae290 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.road.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.road module +===================================== + +.. automodule:: dragonfly_energy.opendss.road + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.rst.txt b/docs/_sources/dragonfly_energy.opendss.rst.txt new file mode 100644 index 00000000..245e0566 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.rst.txt @@ -0,0 +1,36 @@ +dragonfly\_energy.opendss package +================================= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy.opendss.lib + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy.opendss.colorobj + dragonfly_energy.opendss.connector + dragonfly_energy.opendss.junction + dragonfly_energy.opendss.network + dragonfly_energy.opendss.powerline + dragonfly_energy.opendss.result + dragonfly_energy.opendss.road + dragonfly_energy.opendss.substation + dragonfly_energy.opendss.transformer + dragonfly_energy.opendss.transformerprop + dragonfly_energy.opendss.wire + +Module contents +--------------- + +.. automodule:: dragonfly_energy.opendss + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.substation.rst.txt b/docs/_sources/dragonfly_energy.opendss.substation.rst.txt new file mode 100644 index 00000000..62027106 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.substation.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.substation module +=========================================== + +.. automodule:: dragonfly_energy.opendss.substation + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.transformer.rst.txt b/docs/_sources/dragonfly_energy.opendss.transformer.rst.txt new file mode 100644 index 00000000..24848492 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.transformer.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.transformer module +============================================ + +.. automodule:: dragonfly_energy.opendss.transformer + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.transformerprop.rst.txt b/docs/_sources/dragonfly_energy.opendss.transformerprop.rst.txt new file mode 100644 index 00000000..940c2ff4 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.transformerprop.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.transformerprop module +================================================ + +.. automodule:: dragonfly_energy.opendss.transformerprop + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.opendss.wire.rst.txt b/docs/_sources/dragonfly_energy.opendss.wire.rst.txt new file mode 100644 index 00000000..9a682f34 --- /dev/null +++ b/docs/_sources/dragonfly_energy.opendss.wire.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.opendss.wire module +===================================== + +.. automodule:: dragonfly_energy.opendss.wire + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.properties.building.rst.txt b/docs/_sources/dragonfly_energy.properties.building.rst.txt new file mode 100644 index 00000000..010c7ed8 --- /dev/null +++ b/docs/_sources/dragonfly_energy.properties.building.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.properties.building module +============================================ + +.. automodule:: dragonfly_energy.properties.building + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.properties.context.rst.txt b/docs/_sources/dragonfly_energy.properties.context.rst.txt new file mode 100644 index 00000000..f2a6e0fe --- /dev/null +++ b/docs/_sources/dragonfly_energy.properties.context.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.properties.context module +=========================================== + +.. automodule:: dragonfly_energy.properties.context + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.properties.model.rst.txt b/docs/_sources/dragonfly_energy.properties.model.rst.txt new file mode 100644 index 00000000..733ca189 --- /dev/null +++ b/docs/_sources/dragonfly_energy.properties.model.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.properties.model module +========================================= + +.. automodule:: dragonfly_energy.properties.model + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.properties.room2d.rst.txt b/docs/_sources/dragonfly_energy.properties.room2d.rst.txt new file mode 100644 index 00000000..3bd0fd0a --- /dev/null +++ b/docs/_sources/dragonfly_energy.properties.room2d.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.properties.room2d module +========================================== + +.. automodule:: dragonfly_energy.properties.room2d + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.properties.rst.txt b/docs/_sources/dragonfly_energy.properties.rst.txt new file mode 100644 index 00000000..0b1da7eb --- /dev/null +++ b/docs/_sources/dragonfly_energy.properties.rst.txt @@ -0,0 +1,22 @@ +dragonfly\_energy.properties package +==================================== + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy.properties.building + dragonfly_energy.properties.context + dragonfly_energy.properties.model + dragonfly_energy.properties.room2d + dragonfly_energy.properties.story + +Module contents +--------------- + +.. automodule:: dragonfly_energy.properties + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.properties.story.rst.txt b/docs/_sources/dragonfly_energy.properties.story.rst.txt new file mode 100644 index 00000000..38570b70 --- /dev/null +++ b/docs/_sources/dragonfly_energy.properties.story.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.properties.story module +========================================= + +.. automodule:: dragonfly_energy.properties.story + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.reopt.rst.txt b/docs/_sources/dragonfly_energy.reopt.rst.txt new file mode 100644 index 00000000..c495f02e --- /dev/null +++ b/docs/_sources/dragonfly_energy.reopt.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.reopt module +============================== + +.. automodule:: dragonfly_energy.reopt + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.rst.txt b/docs/_sources/dragonfly_energy.rst.txt new file mode 100644 index 00000000..5e25ca7c --- /dev/null +++ b/docs/_sources/dragonfly_energy.rst.txt @@ -0,0 +1,33 @@ +dragonfly\_energy package +========================= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy.cli + dragonfly_energy.des + dragonfly_energy.opendss + dragonfly_energy.properties + +Submodules +---------- + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy.config + dragonfly_energy.measure + dragonfly_energy.reopt + dragonfly_energy.run + dragonfly_energy.writer + +Module contents +--------------- + +.. automodule:: dragonfly_energy + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.run.rst.txt b/docs/_sources/dragonfly_energy.run.rst.txt new file mode 100644 index 00000000..26d596b9 --- /dev/null +++ b/docs/_sources/dragonfly_energy.run.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.run module +============================ + +.. automodule:: dragonfly_energy.run + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/dragonfly_energy.writer.rst.txt b/docs/_sources/dragonfly_energy.writer.rst.txt new file mode 100644 index 00000000..881d1d28 --- /dev/null +++ b/docs/_sources/dragonfly_energy.writer.rst.txt @@ -0,0 +1,7 @@ +dragonfly\_energy.writer module +=============================== + +.. automodule:: dragonfly_energy.writer + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt new file mode 100644 index 00000000..e80919fe --- /dev/null +++ b/docs/_sources/index.rst.txt @@ -0,0 +1,43 @@ +Welcome to dragonfly-energy's documentation! +============================================ + +.. image:: http://www.ladybug.tools/assets/img/dragonfly.png + +`EnergyPlus `_ extension for `dragonfly `_ + +Dragonfly-energy adds EnergyPlus/OpenStudio functionalities to dragonfly for energy simulation. + + +Installation +============ + +``pip install -U dragonfly-energy``. + +To check if the command line is installed correctly use ``dragonfly-energy --help`` + +CLI Docs +============= + +For command line interface documentation and API documentation see the pages below. + + +.. toctree:: + :maxdepth: 2 + + cli/index + + +dragonfly_energy +================ + +.. toctree:: + :maxdepth: 4 + + modules + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/_sources/modules.rst.txt b/docs/_sources/modules.rst.txt new file mode 100644 index 00000000..8be11389 --- /dev/null +++ b/docs/_sources/modules.rst.txt @@ -0,0 +1,7 @@ +dragonfly_energy +================ + +.. toctree:: + :maxdepth: 4 + + dragonfly_energy diff --git a/docs/_static/basic.css b/docs/_static/basic.css new file mode 100644 index 00000000..f316efcb --- /dev/null +++ b/docs/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css b/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css new file mode 100644 index 00000000..09e88ce3 --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.css @@ -0,0 +1,1109 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +@-ms-viewport { + width: device-width; +} + +.hidden { + display: none; + visibility: hidden; +} + +.visible-phone { + display: none !important; +} + +.visible-tablet { + display: none !important; +} + +.hidden-desktop { + display: none !important; +} + +.visible-desktop { + display: inherit !important; +} + +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} + +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} + +.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} + +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.564102564102564%; + *margin-left: 2.5109110747408616%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.564102564102564%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145299145%; + *width: 91.39979996362975%; + } + .row-fluid .span10 { + width: 82.90598290598291%; + *width: 82.8527914166212%; + } + .row-fluid .span9 { + width: 74.35897435897436%; + *width: 74.30578286961266%; + } + .row-fluid .span8 { + width: 65.81196581196582%; + *width: 65.75877432260411%; + } + .row-fluid .span7 { + width: 57.26495726495726%; + *width: 57.21176577559556%; + } + .row-fluid .span6 { + width: 48.717948717948715%; + *width: 48.664757228587014%; + } + .row-fluid .span5 { + width: 40.17094017094017%; + *width: 40.11774868157847%; + } + .row-fluid .span4 { + width: 31.623931623931625%; + *width: 31.570740134569924%; + } + .row-fluid .span3 { + width: 23.076923076923077%; + *width: 23.023731587561375%; + } + .row-fluid .span2 { + width: 14.52991452991453%; + *width: 14.476723040552828%; + } + .row-fluid .span1 { + width: 5.982905982905983%; + *width: 5.929714493544281%; + } + .row-fluid .offset12 { + margin-left: 105.12820512820512%; + *margin-left: 105.02182214948171%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256410257%; + *margin-left: 102.45771958537915%; + } + .row-fluid .offset11 { + margin-left: 96.58119658119658%; + *margin-left: 96.47481360247316%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709401709402%; + *margin-left: 93.91071103837061%; + } + .row-fluid .offset10 { + margin-left: 88.03418803418803%; + *margin-left: 87.92780505546462%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547008548%; + *margin-left: 85.36370249136206%; + } + .row-fluid .offset9 { + margin-left: 79.48717948717949%; + *margin-left: 79.38079650845607%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692307693%; + *margin-left: 76.81669394435352%; + } + .row-fluid .offset8 { + margin-left: 70.94017094017094%; + *margin-left: 70.83378796144753%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606837606839%; + *margin-left: 68.26968539734497%; + } + .row-fluid .offset7 { + margin-left: 62.393162393162385%; + *margin-left: 62.28677941443899%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905982905982%; + *margin-left: 59.72267685033642%; + } + .row-fluid .offset6 { + margin-left: 53.84615384615384%; + *margin-left: 53.739770867430444%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128205128%; + *margin-left: 51.175668303327875%; + } + .row-fluid .offset5 { + margin-left: 45.299145299145295%; + *margin-left: 45.1927623204219%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504273504273%; + *margin-left: 42.62865975631933%; + } + .row-fluid .offset4 { + margin-left: 36.75213675213675%; + *margin-left: 36.645753773413354%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803418803419%; + *margin-left: 34.081651209310785%; + } + .row-fluid .offset3 { + margin-left: 28.205128205128204%; + *margin-left: 28.0987452264048%; + } + .row-fluid .offset3:first-child { + margin-left: 25.641025641025642%; + *margin-left: 25.53464266230224%; + } + .row-fluid .offset2 { + margin-left: 19.65811965811966%; + *margin-left: 19.551736679396257%; + } + .row-fluid .offset2:first-child { + margin-left: 17.094017094017094%; + *margin-left: 16.98763411529369%; + } + .row-fluid .offset1 { + margin-left: 11.11111111111111%; + *margin-left: 11.004728132387708%; + } + .row-fluid .offset1:first-child { + margin-left: 8.547008547008547%; + *margin-left: 8.440625568285142%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} + +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.7624309392265194%; + *margin-left: 2.709239449864817%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.7624309392265194%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.43646408839778%; + *width: 91.38327259903608%; + } + .row-fluid .span10 { + width: 82.87292817679558%; + *width: 82.81973668743387%; + } + .row-fluid .span9 { + width: 74.30939226519337%; + *width: 74.25620077583166%; + } + .row-fluid .span8 { + width: 65.74585635359117%; + *width: 65.69266486422946%; + } + .row-fluid .span7 { + width: 57.18232044198895%; + *width: 57.12912895262725%; + } + .row-fluid .span6 { + width: 48.61878453038674%; + *width: 48.56559304102504%; + } + .row-fluid .span5 { + width: 40.05524861878453%; + *width: 40.00205712942283%; + } + .row-fluid .span4 { + width: 31.491712707182323%; + *width: 31.43852121782062%; + } + .row-fluid .span3 { + width: 22.92817679558011%; + *width: 22.87498530621841%; + } + .row-fluid .span2 { + width: 14.3646408839779%; + *width: 14.311449394616199%; + } + .row-fluid .span1 { + width: 5.801104972375691%; + *width: 5.747913483013988%; + } + .row-fluid .offset12 { + margin-left: 105.52486187845304%; + *margin-left: 105.41847889972962%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243093922652%; + *margin-left: 102.6560479605031%; + } + .row-fluid .offset11 { + margin-left: 96.96132596685082%; + *margin-left: 96.8549429881274%; + } + .row-fluid .offset11:first-child { + margin-left: 94.1988950276243%; + *margin-left: 94.09251204890089%; + } + .row-fluid .offset10 { + margin-left: 88.39779005524862%; + *margin-left: 88.2914070765252%; + } + .row-fluid .offset10:first-child { + margin-left: 85.6353591160221%; + *margin-left: 85.52897613729868%; + } + .row-fluid .offset9 { + margin-left: 79.8342541436464%; + *margin-left: 79.72787116492299%; + } + .row-fluid .offset9:first-child { + margin-left: 77.07182320441989%; + *margin-left: 76.96544022569647%; + } + .row-fluid .offset8 { + margin-left: 71.2707182320442%; + *margin-left: 71.16433525332079%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729281768%; + *margin-left: 68.40190431409427%; + } + .row-fluid .offset7 { + margin-left: 62.70718232044199%; + *margin-left: 62.600799341718584%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138121547%; + *margin-left: 59.838368402492065%; + } + .row-fluid .offset6 { + margin-left: 54.14364640883978%; + *margin-left: 54.037263430116376%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121546961326%; + *margin-left: 51.27483249088986%; + } + .row-fluid .offset5 { + margin-left: 45.58011049723757%; + *margin-left: 45.47372751851417%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767955801105%; + *margin-left: 42.71129657928765%; + } + .row-fluid .offset4 { + margin-left: 37.01657458563536%; + *margin-left: 36.91019160691196%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414364640884%; + *margin-left: 34.14776066768544%; + } + .row-fluid .offset3 { + margin-left: 28.45303867403315%; + *margin-left: 28.346655695309746%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773480663%; + *margin-left: 25.584224756083227%; + } + .row-fluid .offset2 { + margin-left: 19.88950276243094%; + *margin-left: 19.783119783707537%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182320442%; + *margin-left: 17.02068884448102%; + } + .row-fluid .offset1 { + margin-left: 11.32596685082873%; + *margin-left: 11.219583872105325%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591160221%; + *margin-left: 8.457152932878806%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} + +@media (max-width: 767px) { + body { + padding-right: 20px; + padding-left: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-right: -20px; + margin-left: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + width: auto; + clear: none; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + display: block; + float: none; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + right: 20px; + left: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} + +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 20px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-right: 10px; + padding-left: 10px; + } + .media .pull-left, + .media .pull-right { + display: block; + float: none; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + right: 10px; + left: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} + +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 20px; + } + .navbar-fixed-bottom { + margin-top: 20px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-right: 10px; + padding-left: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 10px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + padding: 0; + margin-top: 5px; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + display: none; + float: none; + max-width: none; + padding: 0; + margin: 0 15px; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10px 15px; + margin: 10px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + height: 0; + overflow: hidden; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-right: 10px; + padding-left: 10px; + } +} + +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css b/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css new file mode 100644 index 00000000..f4ede63f --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/docs/_static/bootstrap-2.3.2/css/bootstrap.css b/docs/_static/bootstrap-2.3.2/css/bootstrap.css new file mode 100644 index 00000000..b725064a --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/css/bootstrap.css @@ -0,0 +1,6167 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +audio:not([controls]) { + display: none; +} + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +a:hover, +a:active { + outline: 0; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + width: auto\9; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} + +#map_canvas img, +.google-maps img { + max-width: none; +} + +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} + +button, +input { + *overflow: visible; + line-height: normal; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} + +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 20px; + color: #333333; + background-color: #ffffff; +} + +a { + color: #0088cc; + text-decoration: none; +} + +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} + +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} + +.row { + margin-left: -20px; + *zoom: 1; +} + +.row:before, +.row:after { + display: table; + line-height: 0; + content: ""; +} + +.row:after { + clear: both; +} + +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} + +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.span12 { + width: 940px; +} + +.span11 { + width: 860px; +} + +.span10 { + width: 780px; +} + +.span9 { + width: 700px; +} + +.span8 { + width: 620px; +} + +.span7 { + width: 540px; +} + +.span6 { + width: 460px; +} + +.span5 { + width: 380px; +} + +.span4 { + width: 300px; +} + +.span3 { + width: 220px; +} + +.span2 { + width: 140px; +} + +.span1 { + width: 60px; +} + +.offset12 { + margin-left: 980px; +} + +.offset11 { + margin-left: 900px; +} + +.offset10 { + margin-left: 820px; +} + +.offset9 { + margin-left: 740px; +} + +.offset8 { + margin-left: 660px; +} + +.offset7 { + margin-left: 580px; +} + +.offset6 { + margin-left: 500px; +} + +.offset5 { + margin-left: 420px; +} + +.offset4 { + margin-left: 340px; +} + +.offset3 { + margin-left: 260px; +} + +.offset2 { + margin-left: 180px; +} + +.offset1 { + margin-left: 100px; +} + +.row-fluid { + width: 100%; + *zoom: 1; +} + +.row-fluid:before, +.row-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.row-fluid:after { + clear: both; +} + +.row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.127659574468085%; + *margin-left: 2.074468085106383%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} + +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.127659574468085%; +} + +.row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; +} + +.row-fluid .span11 { + width: 91.48936170212765%; + *width: 91.43617021276594%; +} + +.row-fluid .span10 { + width: 82.97872340425532%; + *width: 82.92553191489361%; +} + +.row-fluid .span9 { + width: 74.46808510638297%; + *width: 74.41489361702126%; +} + +.row-fluid .span8 { + width: 65.95744680851064%; + *width: 65.90425531914893%; +} + +.row-fluid .span7 { + width: 57.44680851063829%; + *width: 57.39361702127659%; +} + +.row-fluid .span6 { + width: 48.93617021276595%; + *width: 48.88297872340425%; +} + +.row-fluid .span5 { + width: 40.42553191489362%; + *width: 40.37234042553192%; +} + +.row-fluid .span4 { + width: 31.914893617021278%; + *width: 31.861702127659576%; +} + +.row-fluid .span3 { + width: 23.404255319148934%; + *width: 23.351063829787233%; +} + +.row-fluid .span2 { + width: 14.893617021276595%; + *width: 14.840425531914894%; +} + +.row-fluid .span1 { + width: 6.382978723404255%; + *width: 6.329787234042553%; +} + +.row-fluid .offset12 { + margin-left: 104.25531914893617%; + *margin-left: 104.14893617021275%; +} + +.row-fluid .offset12:first-child { + margin-left: 102.12765957446808%; + *margin-left: 102.02127659574467%; +} + +.row-fluid .offset11 { + margin-left: 95.74468085106382%; + *margin-left: 95.6382978723404%; +} + +.row-fluid .offset11:first-child { + margin-left: 93.61702127659574%; + *margin-left: 93.51063829787232%; +} + +.row-fluid .offset10 { + margin-left: 87.23404255319149%; + *margin-left: 87.12765957446807%; +} + +.row-fluid .offset10:first-child { + margin-left: 85.1063829787234%; + *margin-left: 84.99999999999999%; +} + +.row-fluid .offset9 { + margin-left: 78.72340425531914%; + *margin-left: 78.61702127659572%; +} + +.row-fluid .offset9:first-child { + margin-left: 76.59574468085106%; + *margin-left: 76.48936170212764%; +} + +.row-fluid .offset8 { + margin-left: 70.2127659574468%; + *margin-left: 70.10638297872339%; +} + +.row-fluid .offset8:first-child { + margin-left: 68.08510638297872%; + *margin-left: 67.9787234042553%; +} + +.row-fluid .offset7 { + margin-left: 61.70212765957446%; + *margin-left: 61.59574468085106%; +} + +.row-fluid .offset7:first-child { + margin-left: 59.574468085106375%; + *margin-left: 59.46808510638297%; +} + +.row-fluid .offset6 { + margin-left: 53.191489361702125%; + *margin-left: 53.085106382978715%; +} + +.row-fluid .offset6:first-child { + margin-left: 51.063829787234035%; + *margin-left: 50.95744680851063%; +} + +.row-fluid .offset5 { + margin-left: 44.68085106382979%; + *margin-left: 44.57446808510638%; +} + +.row-fluid .offset5:first-child { + margin-left: 42.5531914893617%; + *margin-left: 42.4468085106383%; +} + +.row-fluid .offset4 { + margin-left: 36.170212765957444%; + *margin-left: 36.06382978723405%; +} + +.row-fluid .offset4:first-child { + margin-left: 34.04255319148936%; + *margin-left: 33.93617021276596%; +} + +.row-fluid .offset3 { + margin-left: 27.659574468085104%; + *margin-left: 27.5531914893617%; +} + +.row-fluid .offset3:first-child { + margin-left: 25.53191489361702%; + *margin-left: 25.425531914893618%; +} + +.row-fluid .offset2 { + margin-left: 19.148936170212764%; + *margin-left: 19.04255319148936%; +} + +.row-fluid .offset2:first-child { + margin-left: 17.02127659574468%; + *margin-left: 16.914893617021278%; +} + +.row-fluid .offset1 { + margin-left: 10.638297872340425%; + *margin-left: 10.53191489361702%; +} + +.row-fluid .offset1:first-child { + margin-left: 8.51063829787234%; + *margin-left: 8.404255319148938%; +} + +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} + +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} + +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} + +.container:before, +.container:after { + display: table; + line-height: 0; + content: ""; +} + +.container:after { + clear: both; +} + +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} + +.container-fluid:before, +.container-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.container-fluid:after { + clear: both; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 21px; + font-weight: 200; + line-height: 30px; +} + +small { + font-size: 85%; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +cite { + font-style: normal; +} + +.muted { + color: #999999; +} + +a.muted:hover, +a.muted:focus { + color: #808080; +} + +.text-warning { + color: #c09853; +} + +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} + +.text-error { + color: #b94a48; +} + +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} + +.text-info { + color: #3a87ad; +} + +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} + +.text-success { + color: #468847; +} + +a.text-success:hover, +a.text-success:focus { + color: #356635; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0; + font-family: inherit; + font-weight: bold; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + line-height: 40px; +} + +h1 { + font-size: 38.5px; +} + +h2 { + font-size: 31.5px; +} + +h3 { + font-size: 24.5px; +} + +h4 { + font-size: 17.5px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 11.9px; +} + +h1 small { + font-size: 24.5px; +} + +h2 small { + font-size: 17.5px; +} + +h3 small { + font-size: 14px; +} + +h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 20px 0 30px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + padding: 0; + margin: 0 0 10px 25px; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} + +li { + line-height: 20px; +} + +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} + +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} + +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + padding-right: 5px; + padding-left: 5px; + *zoom: 1; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 20px; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 10px; +} + +.dl-horizontal { + *zoom: 1; +} + +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + line-height: 0; + content: ""; +} + +.dl-horizontal:after { + clear: both; +} + +.dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dl-horizontal dd { + margin-left: 180px; +} + +hr { + margin: 20px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + margin-bottom: 0; + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} + +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +code { + padding: 2px 4px; + color: #d14; + white-space: nowrap; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +form { + margin: 0 0 20px; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +legend small { + font-size: 15px; + color: #999999; +} + +label, +input, +button, +select, +textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +label { + display: block; + margin-bottom: 5px; +} + +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 20px; + padding: 4px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: #555555; + vertical-align: middle; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +input, +textarea, +.uneditable-input { + width: 206px; +} + +textarea { + height: auto; +} + +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} + +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + *margin-top: 0; + line-height: normal; +} + +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} + +select, +input[type="file"] { + height: 30px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 30px; +} + +select { + width: 220px; + background-color: #ffffff; + border: 1px solid #cccccc; +} + +select[multiple], +select[size] { + height: auto; +} + +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.uneditable-input, +.uneditable-textarea { + color: #999999; + cursor: not-allowed; + background-color: #fcfcfc; + border-color: #cccccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} + +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} + +.uneditable-textarea { + width: auto; + height: auto; +} + +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} + +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} + +.radio, +.checkbox { + min-height: 20px; + padding-left: 20px; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} + +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} + +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} + +.input-mini { + width: 60px; +} + +.input-small { + width: 90px; +} + +.input-medium { + width: 150px; +} + +.input-large { + width: 210px; +} + +.input-xlarge { + width: 270px; +} + +.input-xxlarge { + width: 530px; +} + +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} + +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +input, +textarea, +.uneditable-input { + margin-left: 0; +} + +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} + +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} + +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} + +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} + +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} + +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} + +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} + +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} + +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} + +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} + +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} + +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} + +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} + +.controls-row { + *zoom: 1; +} + +.controls-row:before, +.controls-row:after { + display: table; + line-height: 0; + content: ""; +} + +.controls-row:after { + clear: both; +} + +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} + +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} + +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} + +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} + +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} + +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} + +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} + +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} + +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} + +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} + +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} + +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} + +.form-actions { + padding: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} + +.form-actions:before, +.form-actions:after { + display: table; + line-height: 0; + content: ""; +} + +.form-actions:after { + clear: both; +} + +.help-block, +.help-inline { + color: #595959; +} + +.help-block { + display: block; + margin-bottom: 10px; +} + +.help-inline { + display: inline-block; + *display: inline; + padding-left: 5px; + vertical-align: middle; + *zoom: 1; +} + +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10px; + font-size: 0; + white-space: nowrap; + vertical-align: middle; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 14px; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} + +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} + +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} + +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} + +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} + +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/* Allow for input prepend/append in search forms */ + +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; +} + +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} + +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} + +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} + +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} + +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + +.control-group { + margin-bottom: 10px; +} + +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} + +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} + +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; +} + +.form-horizontal .control-group:after { + clear: both; +} + +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} + +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} + +.form-horizontal .controls:first-child { + *padding-left: 180px; +} + +.form-horizontal .help-block { + margin-bottom: 0; +} + +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10px; +} + +.form-horizontal .form-actions { + padding-left: 180px; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table th { + font-weight: bold; +} + +.table thead th { + vertical-align: bottom; +} + +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} + +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; +} + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} + +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} + +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} + +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} + +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} + +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} + +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} + +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} + +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} + +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} + +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} + +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} + +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} + +.table tbody tr.success > td { + background-color: #dff0d8; +} + +.table tbody tr.error > td { + background-color: #f2dede; +} + +.table tbody tr.warning > td { + background-color: #fcf8e3; +} + +.table tbody tr.info > td { + background-color: #d9edf7; +} + +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} + +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} + +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} + +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} + +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-top: 1px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} + +/* White icons with optional class, or on hover/focus/active states of certain elements */ + +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + background-image: url("../img/glyphicons-halflings-white.png"); +} + +.icon-glass { + background-position: 0 0; +} + +.icon-music { + background-position: -24px 0; +} + +.icon-search { + background-position: -48px 0; +} + +.icon-envelope { + background-position: -72px 0; +} + +.icon-heart { + background-position: -96px 0; +} + +.icon-star { + background-position: -120px 0; +} + +.icon-star-empty { + background-position: -144px 0; +} + +.icon-user { + background-position: -168px 0; +} + +.icon-film { + background-position: -192px 0; +} + +.icon-th-large { + background-position: -216px 0; +} + +.icon-th { + background-position: -240px 0; +} + +.icon-th-list { + background-position: -264px 0; +} + +.icon-ok { + background-position: -288px 0; +} + +.icon-remove { + background-position: -312px 0; +} + +.icon-zoom-in { + background-position: -336px 0; +} + +.icon-zoom-out { + background-position: -360px 0; +} + +.icon-off { + background-position: -384px 0; +} + +.icon-signal { + background-position: -408px 0; +} + +.icon-cog { + background-position: -432px 0; +} + +.icon-trash { + background-position: -456px 0; +} + +.icon-home { + background-position: 0 -24px; +} + +.icon-file { + background-position: -24px -24px; +} + +.icon-time { + background-position: -48px -24px; +} + +.icon-road { + background-position: -72px -24px; +} + +.icon-download-alt { + background-position: -96px -24px; +} + +.icon-download { + background-position: -120px -24px; +} + +.icon-upload { + background-position: -144px -24px; +} + +.icon-inbox { + background-position: -168px -24px; +} + +.icon-play-circle { + background-position: -192px -24px; +} + +.icon-repeat { + background-position: -216px -24px; +} + +.icon-refresh { + background-position: -240px -24px; +} + +.icon-list-alt { + background-position: -264px -24px; +} + +.icon-lock { + background-position: -287px -24px; +} + +.icon-flag { + background-position: -312px -24px; +} + +.icon-headphones { + background-position: -336px -24px; +} + +.icon-volume-off { + background-position: -360px -24px; +} + +.icon-volume-down { + background-position: -384px -24px; +} + +.icon-volume-up { + background-position: -408px -24px; +} + +.icon-qrcode { + background-position: -432px -24px; +} + +.icon-barcode { + background-position: -456px -24px; +} + +.icon-tag { + background-position: 0 -48px; +} + +.icon-tags { + background-position: -25px -48px; +} + +.icon-book { + background-position: -48px -48px; +} + +.icon-bookmark { + background-position: -72px -48px; +} + +.icon-print { + background-position: -96px -48px; +} + +.icon-camera { + background-position: -120px -48px; +} + +.icon-font { + background-position: -144px -48px; +} + +.icon-bold { + background-position: -167px -48px; +} + +.icon-italic { + background-position: -192px -48px; +} + +.icon-text-height { + background-position: -216px -48px; +} + +.icon-text-width { + background-position: -240px -48px; +} + +.icon-align-left { + background-position: -264px -48px; +} + +.icon-align-center { + background-position: -288px -48px; +} + +.icon-align-right { + background-position: -312px -48px; +} + +.icon-align-justify { + background-position: -336px -48px; +} + +.icon-list { + background-position: -360px -48px; +} + +.icon-indent-left { + background-position: -384px -48px; +} + +.icon-indent-right { + background-position: -408px -48px; +} + +.icon-facetime-video { + background-position: -432px -48px; +} + +.icon-picture { + background-position: -456px -48px; +} + +.icon-pencil { + background-position: 0 -72px; +} + +.icon-map-marker { + background-position: -24px -72px; +} + +.icon-adjust { + background-position: -48px -72px; +} + +.icon-tint { + background-position: -72px -72px; +} + +.icon-edit { + background-position: -96px -72px; +} + +.icon-share { + background-position: -120px -72px; +} + +.icon-check { + background-position: -144px -72px; +} + +.icon-move { + background-position: -168px -72px; +} + +.icon-step-backward { + background-position: -192px -72px; +} + +.icon-fast-backward { + background-position: -216px -72px; +} + +.icon-backward { + background-position: -240px -72px; +} + +.icon-play { + background-position: -264px -72px; +} + +.icon-pause { + background-position: -288px -72px; +} + +.icon-stop { + background-position: -312px -72px; +} + +.icon-forward { + background-position: -336px -72px; +} + +.icon-fast-forward { + background-position: -360px -72px; +} + +.icon-step-forward { + background-position: -384px -72px; +} + +.icon-eject { + background-position: -408px -72px; +} + +.icon-chevron-left { + background-position: -432px -72px; +} + +.icon-chevron-right { + background-position: -456px -72px; +} + +.icon-plus-sign { + background-position: 0 -96px; +} + +.icon-minus-sign { + background-position: -24px -96px; +} + +.icon-remove-sign { + background-position: -48px -96px; +} + +.icon-ok-sign { + background-position: -72px -96px; +} + +.icon-question-sign { + background-position: -96px -96px; +} + +.icon-info-sign { + background-position: -120px -96px; +} + +.icon-screenshot { + background-position: -144px -96px; +} + +.icon-remove-circle { + background-position: -168px -96px; +} + +.icon-ok-circle { + background-position: -192px -96px; +} + +.icon-ban-circle { + background-position: -216px -96px; +} + +.icon-arrow-left { + background-position: -240px -96px; +} + +.icon-arrow-right { + background-position: -264px -96px; +} + +.icon-arrow-up { + background-position: -289px -96px; +} + +.icon-arrow-down { + background-position: -312px -96px; +} + +.icon-share-alt { + background-position: -336px -96px; +} + +.icon-resize-full { + background-position: -360px -96px; +} + +.icon-resize-small { + background-position: -384px -96px; +} + +.icon-plus { + background-position: -408px -96px; +} + +.icon-minus { + background-position: -433px -96px; +} + +.icon-asterisk { + background-position: -456px -96px; +} + +.icon-exclamation-sign { + background-position: 0 -120px; +} + +.icon-gift { + background-position: -24px -120px; +} + +.icon-leaf { + background-position: -48px -120px; +} + +.icon-fire { + background-position: -72px -120px; +} + +.icon-eye-open { + background-position: -96px -120px; +} + +.icon-eye-close { + background-position: -120px -120px; +} + +.icon-warning-sign { + background-position: -144px -120px; +} + +.icon-plane { + background-position: -168px -120px; +} + +.icon-calendar { + background-position: -192px -120px; +} + +.icon-random { + width: 16px; + background-position: -216px -120px; +} + +.icon-comment { + background-position: -240px -120px; +} + +.icon-magnet { + background-position: -264px -120px; +} + +.icon-chevron-up { + background-position: -288px -120px; +} + +.icon-chevron-down { + background-position: -313px -119px; +} + +.icon-retweet { + background-position: -336px -120px; +} + +.icon-shopping-cart { + background-position: -360px -120px; +} + +.icon-folder-close { + width: 16px; + background-position: -384px -120px; +} + +.icon-folder-open { + width: 16px; + background-position: -408px -120px; +} + +.icon-resize-vertical { + background-position: -432px -119px; +} + +.icon-resize-horizontal { + background-position: -456px -118px; +} + +.icon-hdd { + background-position: 0 -144px; +} + +.icon-bullhorn { + background-position: -24px -144px; +} + +.icon-bell { + background-position: -48px -144px; +} + +.icon-certificate { + background-position: -72px -144px; +} + +.icon-thumbs-up { + background-position: -96px -144px; +} + +.icon-thumbs-down { + background-position: -120px -144px; +} + +.icon-hand-right { + background-position: -144px -144px; +} + +.icon-hand-left { + background-position: -168px -144px; +} + +.icon-hand-up { + background-position: -192px -144px; +} + +.icon-hand-down { + background-position: -216px -144px; +} + +.icon-circle-arrow-right { + background-position: -240px -144px; +} + +.icon-circle-arrow-left { + background-position: -264px -144px; +} + +.icon-circle-arrow-up { + background-position: -288px -144px; +} + +.icon-circle-arrow-down { + background-position: -312px -144px; +} + +.icon-globe { + background-position: -336px -144px; +} + +.icon-wrench { + background-position: -360px -144px; +} + +.icon-tasks { + background-position: -384px -144px; +} + +.icon-filter { + background-position: -408px -144px; +} + +.icon-briefcase { + background-position: -432px -144px; +} + +.icon-fullscreen { + background-position: -456px -144px; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle { + *margin-bottom: -3px; +} + +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} + +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + outline: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open { + *z-index: 1000; +} + +.open > .dropdown-menu { + display: block; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} + +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} + +.dropdown-submenu > a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + border-left-color: #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; +} + +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.dropdown .dropdown-menu .nav-header { + padding-right: 20px; + padding-left: 20px; +} + +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +.collapse.in { + height: auto; +} + +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 20px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.btn { + display: inline-block; + *display: inline; + padding: 4px 12px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + *background-color: #e6e6e6; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border: 1px solid #cccccc; + *border: 0; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} + +.btn:active, +.btn.active { + background-color: #cccccc \9; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +.btn-mini { + padding: 0 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + *background-color: #f89406; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} + +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + *background-color: #bd362f; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} + +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + *background-color: #51a351; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} + +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + *background-color: #2f96b4; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} + +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + *background-color: #222222; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} + +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} + +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} + +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} + +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-link { + color: #0088cc; + cursor: pointer; + border-color: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} + +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *margin-left: .3em; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + *zoom: 1; +} + +.btn-group:first-child { + *margin-left: 0; +} + +.btn-group + .btn-group { + margin-left: 5px; +} + +.btn-toolbar { + margin-top: 10px; + margin-bottom: 10px; + font-size: 0; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group > .btn + .btn { + margin-left: -1px; +} + +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 14px; +} + +.btn-group > .btn-mini { + font-size: 10.5px; +} + +.btn-group > .btn-small { + font-size: 11.9px; +} + +.btn-group > .btn-large { + font-size: 17.5px; +} + +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group > .btn + .dropdown-toggle { + *padding-top: 5px; + padding-right: 8px; + *padding-bottom: 5px; + padding-left: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group > .btn-mini + .dropdown-toggle { + *padding-top: 2px; + padding-right: 5px; + *padding-bottom: 2px; + padding-left: 5px; +} + +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} + +.btn-group > .btn-large + .dropdown-toggle { + *padding-top: 7px; + padding-right: 12px; + *padding-bottom: 7px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} + +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} + +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} + +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} + +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} + +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} + +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} + +.btn .caret { + margin-top: 8px; + margin-left: 0; +} + +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} + +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} + +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group-vertical > .btn + .btn { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} + +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.alert, +.alert h4 { + color: #c09853; +} + +.alert h4 { + margin: 0; +} + +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success h4 { + color: #468847; +} + +.alert-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info h4 { + color: #3a87ad; +} + +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} + +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} + +.alert-block p + p { + margin-top: 5px; +} + +.nav { + margin-bottom: 20px; + margin-left: 0; + list-style: none; +} + +.nav > li > a { + display: block; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li > a > img { + max-width: none; +} + +.nav > .pull-right { + float: right; +} + +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} + +.nav li + .nav-header { + margin-top: 9px; +} + +.nav-list { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 0; +} + +.nav-list > li > a, +.nav-list .nav-header { + margin-right: -15px; + margin-left: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.nav-list > li > a { + padding: 3px 15px; +} + +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} + +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} + +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-tabs, +.nav-pills { + *zoom: 1; +} + +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + line-height: 0; + content: ""; +} + +.nav-tabs:after, +.nav-pills:after { + clear: both; +} + +.nav-tabs > li, +.nav-pills > li { + float: left; +} + +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs > li { + margin-bottom: -1px; +} + +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 20px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} + +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li > a { + margin-right: 0; +} + +.nav-tabs.nav-stacked { + border-bottom: 0; +} + +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; +} + +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + z-index: 2; + border-color: #ddd; +} + +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} + +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} + +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.nav .dropdown-toggle .caret { + margin-top: 6px; + border-top-color: #0088cc; + border-bottom-color: #0088cc; +} + +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} + +/* move down carets for tabs */ + +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} + +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} + +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} + +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} + +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} + +.tabbable { + *zoom: 1; +} + +.tabbable:before, +.tabbable:after { + display: table; + line-height: 0; + content: ""; +} + +.tabbable:after { + clear: both; +} + +.tab-content { + overflow: auto; +} + +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} + +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} + +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} + +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} + +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} + +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} + +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} + +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav > .disabled > a { + color: #999999; +} + +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; +} + +.navbar-inner { + min-height: 40px; + padding-right: 20px; + padding-left: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.navbar-inner:before, +.navbar-inner:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-inner:after { + clear: both; +} + +.navbar .container { + width: auto; +} + +.nav-collapse.collapse { + height: auto; + overflow: visible; +} + +.navbar .brand { + display: block; + float: left; + padding: 10px 20px 10px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} + +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-right: 1px solid #ffffff; + border-left: 1px solid #f2f2f2; +} + +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} + +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} + +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} + +.navbar-form:before, +.navbar-form:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-form:after { + clear: both; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} + +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} + +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} + +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} + +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} + +.navbar-search .search-query { + padding: 4px 14px; + margin-bottom: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.navbar-static-top { + position: static; + margin-bottom: 0; +} + +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} + +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-right: 0; + padding-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} + +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} + +.navbar .nav > li { + float: left; +} + +.navbar .nav > li > a { + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} + +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + color: #333333; + text-decoration: none; + background-color: transparent; +} + +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} + +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-right: 5px; + margin-left: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + *background-color: #e5e5e5; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} + +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} + +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} + +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} + +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} + +.navbar .nav > li > .dropdown-menu:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.navbar .nav > li > .dropdown-menu:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + top: auto; + bottom: -7px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + top: auto; + bottom: -6px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + color: #555555; + background-color: #e5e5e5; +} + +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + right: 12px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + right: 13px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + right: 100%; + left: auto; + margin-right: -1px; + margin-left: 0; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + border-color: #252525; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); +} + +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} + +.navbar-inverse .brand { + color: #999999; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} + +.navbar-inverse .divider-vertical { + border-right-color: #222222; + border-left-color: #111111; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} + +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} + +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + *background-color: #040404; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} + +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} + +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; + *display: inline; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + margin: 20px 0; +} + +.pagination ul { + display: inline-block; + *display: inline; + margin-bottom: 0; + margin-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.pagination ul > li { + display: inline; +} + +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} + +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} + +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} + +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + cursor: default; + background-color: transparent; +} + +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.pagination-centered { + text-align: center; +} + +.pagination-right { + text-align: right; +} + +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 17.5px; +} + +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-topleft: 3px; +} + +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; +} + +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 11.9px; +} + +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 10.5px; +} + +.pager { + margin: 20px 0; + text-align: center; + list-style: none; + *zoom: 1; +} + +.pager:before, +.pager:after { + display: table; + line-height: 0; + content: ""; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: default; + background-color: #fff; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} + +.modal.fade { + top: -25%; + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -moz-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; +} + +.modal.fade.in { + top: 10%; +} + +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + position: relative; + max-height: 400px; + padding: 15px; + overflow-y: auto; +} + +.modal-form { + margin-bottom: 0; +} + +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + line-height: 0; + content: ""; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.popover-title:empty { + display: none; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; +} + +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} + +.thumbnails:before, +.thumbnails:after { + display: table; + line-height: 0; + content: ""; +} + +.thumbnails:after { + clear: both; +} + +.row-fluid .thumbnails { + margin-left: 0; +} + +.thumbnails > li { + float: left; + margin-bottom: 20px; + margin-left: 20px; +} + +.thumbnail { + display: block; + padding: 4px; + line-height: 20px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} + +.thumbnail > img { + display: block; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #555555; +} + +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + margin-left: 0; + list-style: none; +} + +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; +} + +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.badge { + padding-right: 9px; + padding-left: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} + +.label:empty, +.badge:empty { + display: none; +} + +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label-important, +.badge-important { + background-color: #b94a48; +} + +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} + +.label-warning, +.badge-warning { + background-color: #f89406; +} + +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} + +.label-success, +.badge-success { + background-color: #468847; +} + +.label-success[href], +.badge-success[href] { + background-color: #356635; +} + +.label-info, +.badge-info { + background-color: #3a87ad; +} + +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} + +.label-inverse, +.badge-inverse { + background-color: #333333; +} + +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} + +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} + +.btn-mini .label, +.btn-mini .badge { + top: 0; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.progress .bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); +} + +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} + +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} + +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} + +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} + +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} + +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.accordion { + margin-bottom: 20px; +} + +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.accordion-heading { + border-bottom: 0; +} + +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} + +.accordion-toggle { + cursor: pointer; +} + +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} + +.carousel { + position: relative; + margin-bottom: 20px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.right { + right: 15px; + left: auto; +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} + +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} + +.carousel-caption h4, +.carousel-caption p { + line-height: 20px; + color: #ffffff; +} + +.carousel-caption h4 { + margin: 0 0 5px; +} + +.carousel-caption p { + margin-bottom: 0; +} + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; +} + +.hero-unit li { + line-height: 30px; +} + +.pull-right { + float: right; +} + +.pull-left { + float: left; +} + +.hide { + display: none; +} + +.show { + display: block; +} + +.invisible { + visibility: hidden; +} + +.affix { + position: fixed; +} diff --git a/docs/_static/bootstrap-2.3.2/css/bootstrap.min.css b/docs/_static/bootstrap-2.3.2/css/bootstrap.min.css new file mode 100644 index 00000000..b6428e69 --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/css/bootstrap.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png b/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf6484a29d8da269f9bc874b25493a45fae3bae GIT binary patch literal 8777 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 B7G?kd literal 0 HcmV?d00001 diff --git a/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings.png b/docs/_static/bootstrap-2.3.2/img/glyphicons-halflings.png new file mode 100644 index 0000000000000000000000000000000000000000..a9969993201f9cee63cf9f49217646347297b643 GIT binary patch literal 12799 zcma*OWmH^Ivn@*S;K3nSf_t!#;0f+&pm7Po8`nk}2q8f5;M%x$SdAkd9FAvlc$ zx660V9e3Ox@4WZ^?7jZ%QFGU-T~%||Ug4iK6bbQY@zBuF2$hxOw9wF=A)nUSxR_5@ zEX>HBryGrjyuOFFv$Y4<+|3H@gQfEqD<)+}a~mryD|1U9*I_FOG&F%+Ww{SJ-V2BR zjt<81Ek$}Yb*95D4RS0HCps|uLyovt;P05hchQb-u2bzLtmog&f2}1VlNhxXV);S9 zM2buBg~!q9PtF)&KGRgf3#z7B(hm5WlNClaCWFs!-P!4-u*u5+=+D|ZE9e`KvhTHT zJBnLwGM%!u&vlE%1ytJ=!xt~y_YkFLQb6bS!E+s8l7PiPGSt9xrmg?LV&&SL?J~cI zS(e9TF1?SGyh+M_p@o1dyWu7o7_6p;N6hO!;4~ z2B`I;y`;$ZdtBpvK5%oQ^p4eR2L)BH>B$FQeC*t)c`L71gXHPUa|vyu`Bnz)H$ZcXGve(}XvR!+*8a>BLV;+ryG1kt0=)ytl zNJxFUN{V7P?#|Cp85QTa@(*Q3%K-R(Pkv1N8YU*(d(Y}9?PQ(j;NzWoEVWRD-~H$=f>j9~PN^BM2okI(gY-&_&BCV6RP&I$FnSEM3d=0fCxbxA6~l>54-upTrw zYgX@%m>jsSGi`0cQt6b8cX~+02IghVlNblR7eI;0ps}mpWUcxty1yG56C5rh%ep(X z?)#2d?C<4t-KLc*EAn>>M8%HvC1TyBSoPNg(4id~H8JwO#I)Bf;N*y6ai6K9_bA`4 z_g9(-R;qyH&6I$`b42v|0V3Z8IXN*p*8g$gE98+JpXNY+jXxU0zsR^W$#V=KP z3AEFp@OL}WqwOfsV<)A^UTF4&HF1vQecz?LWE@p^Z2){=KEC_3Iopx_eS42>DeiDG zWMXGbYfG~W7C8s@@m<_?#Gqk;!&)_Key@^0xJxrJahv{B&{^!>TV7TEDZlP|$=ZCz zmX=ZWtt4QZKx**)lQQoW8y-XLiOQy#T`2t}p6l*S`68ojyH@UXJ-b~@tN`WpjF z%7%Yzv807gsO!v=!(2uR)16!&U5~VPrPHtGzUU?2w(b1Xchq}(5Ed^G|SD7IG+kvgyVksU) z(0R)SW1V(>&q2nM%Z!C9=;pTg!(8pPSc%H01urXmQI6Gi^dkYCYfu6b4^tW))b^U+ z$2K&iOgN_OU7n#GC2jgiXU{caO5hZt0(>k+c^(r><#m|#J^s?zA6pi;^#*rp&;aqL zRcZi0Q4HhVX3$ybclxo4FFJW*`IV`)Bj_L3rQe?5{wLJh168Ve1jZv+f1D}f0S$N= zm4i|9cEWz&C9~ZI3q*gwWH^<6sBWuphgy@S3Qy?MJiL>gwd|E<2h9-$3;gT9V~S6r z)cAcmE0KXOwDA5eJ02-75d~f?3;n7a9d_xPBJaO;Z)#@s7gk5$Qn(Fc^w@9c5W0zY z59is0?Mt^@Rolcn{4%)Ioat(kxQH6}hIykSA)zht=9F_W*D#<}N(k&&;k;&gKkWIL z0Of*sP=X(Uyu$Pw;?F@?j{}=>{aSHFcii#78FC^6JGrg-)!)MV4AKz>pXnhVgTgx8 z1&5Y=>|8RGA6++FrSy=__k_imx|z-EI@foKi>tK0Hq2LetjUotCgk2QFXaej!BWYL zJc{fv(&qA7UUJ|AXLc5z*_NW#yWzKtl(c8mEW{A>5Hj^gfZ^HC9lQNQ?RowXjmuCj4!!54Us1=hY z0{@-phvC}yls!PmA~_z>Y&n&IW9FQcj}9(OLO-t^NN$c0o}YksCUWt|DV(MJB%%Sr zdf}8!9ylU2TW!=T{?)g-ojAMKc>3pW;KiZ7f0;&g)k}K^#HBhE5ot)%oxq$*$W@b# zg4p<Ou`ME|Kd1WHK@8 zzLD+0(NHWa`B{em3Ye?@aVsEi>y#0XVZfaFuq#;X5C3{*ikRx7UY4FF{ZtNHNO?A_ z#Q?hwRv~D8fPEc%B5E-ZMI&TAmikl||EERumQCRh7p;)>fdZMxvKq;ky0}7IjhJph zW*uuu*(Y6)S;Od--8uR^R#sb$cmFCnPcj9PPCWhPN;n`i1Q#Qn>ii z{WR|0>8F`vf&#E(c2NsoH=I7Cd-FV|%(7a`i}gZw4N~QFFG2WtS^H%@c?%9UZ+kez z;PwGgg_r6V>Kn5n(nZ40P4qMyrCP3bDkJp@hp6&X3>gzC>=f@Hsen<%I~7W+x@}b> z0}Et*vx_50-q@PIV=(3&Tbm}}QRo*FP2@)A#XX-8jYspIhah`9ukPBr)$8>Tmtg&R z?JBoH17?+1@Y@r>anoKPQ}F8o9?vhcG79Cjv^V6ct709VOQwg{c0Q#rBSsSmK3Q;O zBpNihl3S0_IGVE)^`#94#j~$;7+u870yWiV$@={|GrBmuz4b)*bCOPkaN0{6$MvazOEBxFdKZDlbVvv{8_*kJ zfE6C`4&Kkz<5u%dEdStd85-5UHG5IOWbo8i9azgg#zw-(P1AA049hddAB*UdG3Vn0 zX`OgM+EM|<+KhJ<=k?z~WA5waVj?T9eBdfJGebVifBKS1u<$#vl^BvSg)xsnT5Aw_ZY#}v*LXO#htB>f}x3qDdDHoFeb zAq7;0CW;XJ`d&G*9V)@H&739DpfWYzdQt+Kx_E1K#Cg1EMtFa8eQRk_JuUdHD*2;W zR~XFnl!L2A?48O;_iqCVr1oxEXvOIiN_9CUVTZs3C~P+11}ebyTRLACiJuMIG#`xP zKlC|E(S@QvN+%pBc6vPiQS8KgQAUh75C0a2xcPQDD$}*bM&z~g8+=9ltmkT$;c;s z5_=8%i0H^fEAOQbHXf0;?DN5z-5+1 zDxj50yYkz4ox9p$HbZ|H?8ukAbLE^P$@h}L%i6QVcY>)i!w=hkv2zvrduut%!8>6b zcus3bh1w~L804EZ*s96?GB&F7c5?m?|t$-tp2rKMy>F*=4;w*jW}^;8v`st&8)c; z2Ct2{)?S(Z;@_mjAEjb8x=qAQvx=}S6l9?~H?PmP`-xu;ME*B8sm|!h@BX4>u(xg_ zIHmQzp4Tgf*J}Y=8STR5_s)GKcmgV!$JKTg@LO402{{Wrg>#D4-L%vjmtJ4r?p&$F!o-BOf7ej~ z6)BuK^^g1b#(E>$s`t3i13{6-mmSp7{;QkeG5v}GAN&lM2lQT$@(aQCcFP(%UyZbF z#$HLTqGT^@F#A29b0HqiJsRJAlh8kngU`BDI6 zJUE~&!cQ*&f95Ot$#mxU5+*^$qg_DWNdfu+1irglB7yDglzH()2!@#rpu)^3S8weW z_FE$=j^GTY*|5SH95O8o8W9FluYwB=2PwtbW|JG6kcV^dMVmX(wG+Otj;E$%gfu^K z!t~<3??8=()WQSycsBKy24>NjRtuZ>zxJIED;YXaUz$@0z4rl+TW zWxmvM$%4jYIpO>j5k1t1&}1VKM~s!eLsCVQ`TTjn3JRXZD~>GM z$-IT~(Y)flNqDkC%DfbxaV9?QuWCV&-U1yzrV@0jRhE;)ZO0=r-{s@W?HOFbRHDDV zq;eLo+wOW;nI|#mNf(J?RImB9{YSO2Y`9825Lz#u4(nk3)RGv3X8B(A$TsontJ8L! z9JP^eWxtKC?G8^xAZa1HECx*rp35s!^%;&@Jyk)NexVc)@U4$^X1Dag6`WKs|(HhZ#rzO2KEw3xh~-0<;|zcs0L>OcO#YYX{SN8m6`9pp+ zQG@q$I)T?aoe#AoR@%om_#z=c@ych!bj~lV13Qi-xg$i$hXEAB#l=t7QWENGbma4L zbBf*X*4oNYZUd_;1{Ln_ZeAwQv4z?n9$eoxJeI?lU9^!AB2Y~AwOSq67dT9ADZ)s@ zCRYS7W$Zpkdx$3T>7$I%3EI2ik~m!f7&$Djpt6kZqDWZJ-G{*_eXs*B8$1R4+I}Kf zqniwCI64r;>h2Lu{0c(#Atn)%E8&)=0S4BMhq9$`vu|Ct;^ur~gL`bD>J@l)P$q_A zO7b3HGOUG`vgH{}&&AgrFy%K^>? z>wf**coZ2vdSDcNYSm~dZ(vk6&m6bVKmVgrx-X<>{QzA!)2*L+HLTQz$e8UcB&Djq zl)-%s$ZtUN-R!4ZiG=L0#_P=BbUyH+YPmFl_ogkkQ$=s@T1v}rNnZ^eMaqJ|quc+6 z*ygceDOrldsL30w`H;rNu+IjlS+G~p&0SawXCA1+D zC%cZtjUkLNq%FadtHE?O(yQTP486A{1x<{krq#rpauNQaeyhM3*i0%tBpQHQo-u)x z{0{&KS`>}vf2_}b160XZO2$b)cyrHq7ZSeiSbRvaxnKUH{Q`-P(nL&^fcF2){vhN- zbX&WEjP7?b4A%0y6n_=m%l00uZ+}mCYO(!x?j$+O$*TqoD_Q5EoyDJ?w?^UIa491H zE}87(bR`X;@u#3Qy~9wWdWQIg1`cXrk$x9=ccR|RY1~%{fAJ@uq@J3e872x0v$hmv ze_KcL(wM|n0EOp;t{hKoohYyDmYO;!`7^Lx;0k=PWPGZpI>V5qYlzjSL_(%|mud50 z7#{p97s`U|Sn$WYF>-i{i4`kzlrV6a<}=72q2sAT7Zh{>P%*6B;Zl;~0xWymt10Mo zl5{bmR(wJefJpNGK=fSRP|mpCI-)Nf6?Pv==FcFmpSwF1%CTOucV{yqxSyx4Zws3O z8hr5Uyd%ezIO7?PnEO0T%af#KOiXD$e?V&OX-B|ZX-YsgSs%sv-6U+sLPuz{D4bq| zpd&|o5tNCmpT>(uIbRf?8c}d3IpOb3sn6>_dr*26R#ev<_~vi)wleW$PX|5)$_ z+_|=pi(0D(AB_sjQ;sQQSM&AWqzDO1@NHw;C9cPdXRKRI#@nUW)CgFxzQ1nyd!+h& zcjU!U=&u|>@}R(9D$%lu2TlV>@I2-n@fCr5PrZNVyKWR7hm zWjoy^p7v8m#$qN0K#8jT- zq`mSirDZDa1Jxm;Rg3rAPhC)LcI4@-RvKT+@9&KsR3b0_0zuM!Fg7u>oF>3bzOxZPU&$ab$Z9@ zY)f7pKh22I7ZykL{YsdjcqeN++=0a}elQM-4;Q)(`Ep3|VFHqnXOh14`!Bus& z9w%*EWK6AiAM{s$6~SEQS;A>ey$#`7)khZvamem{P?>k)5&7Sl&&NXKk}o!%vd;-! zpo2p-_h^b$DNBO>{h4JdGB=D>fvGIYN8v&XsfxU~VaefL?q} z3ekM?iOKkCzQHkBkhg=hD!@&(L}FcHKoa zbZ7)H1C|lHjwEb@tu=n^OvdHOo7o+W`0-y3KdP#bb~wM=Vr_gyoEq|#B?$&d$tals ziIs-&7isBpvS|CjC|7C&3I0SE?~`a%g~$PI%;au^cUp@ER3?mn-|vyu!$7MV6(uvt z+CcGuM(Ku2&G0tcRCo7#D$Dirfqef2qPOE5I)oCGzmR5G!o#Q~(k~)c=LpIfrhHQk zeAva6MilEifE7rgP1M7AyWmLOXK}i8?=z2;N=no)`IGm#y%aGE>-FN zyXCp0Sln{IsfOBuCdE*#@CQof%jzuU*jkR*Su3?5t}F(#g0BD0Zzu|1MDes8U7f9; z$JBg|mqTXt`muZ8=Z`3wx$uizZG_7>GI7tcfOHW`C2bKxNOR)XAwRkLOaHS4xwlH4 zDpU29#6wLXI;H?0Se`SRa&I_QmI{zo7p%uveBZ0KZKd9H6@U?YGArbfm)D*^5=&Rp z`k{35?Z5GbZnv>z@NmJ%+sx=1WanWg)8r}C_>EGR8mk(NR$pW<-l8OTU^_u3M@gwS z7}GGa1)`z5G|DZirw;FB@VhH7Dq*0qc=|9lLe{w2#`g+_nt>_%o<~9(VZe=zI*SSz4w43-_o>4E4`M@NPKTWZuQJs)?KXbWp1M zimd5F;?AP(LWcaI-^Sl{`~>tmxsQB9Y$Xi*{Zr#py_+I$vx7@NY`S?HFfS!hUiz$a z{>!&e1(16T!Om)m)&k1W#*d#GslD^4!TwiF2WjFBvi=Ms!ADT)ArEW6zfVuIXcXVk z>AHjPADW+mJzY`_Ieq(s?jbk4iD2Rb8*V3t6?I+E06(K8H!!xnDzO%GB;Z$N-{M|B zeT`jo%9)s%op*XZKDd6*)-^lWO{#RaIGFdBH+;XXjI(8RxpBc~azG1H^2v7c^bkFE zZCVPE+E*Q=FSe8Vm&6|^3ki{9~qafiMAf7i4APZg>b%&5>nT@pHH z%O*pOv(77?ZiT{W zBibx}Q12tRc7Py1NcZTp`Q4ey%T_nj@1WKg5Fz_Rjl4wlJQj)rtp8yL3r!Shy zvZvnmh!tH4T6Js-?vI0<-rzzl{mgT*S0d_7^AU_8gBg^03o-J=p(1o6kww2hx|!%T z-jqp}m^G*W?$!R#M%Ef?&2jYxmx+lXWZszpI4d$pUN`(S)|*c^CgdwY>Fa>> zgGBJhwe8y#Xd*q0=@SLEgPF>+Qe4?%E*v{a`||luZ~&dqMBrRfJ{SDMaJ!s_;cSJp zSqZHXIdc@@XteNySUZs^9SG7xK`8=NBNM)fRVOjw)D^)w%L2OPkTQ$Tel-J)GD3=YXy+F4in(ILy*A3m@3o73uv?JC}Q>f zrY&8SWmesiba0|3X-jmlMT3 z*ST|_U@O=i*sM_*48G)dgXqlwoFp5G6qSM3&%_f_*n!PiT>?cNI)fAUkA{qWnqdMi+aNK_yVQ&lx4UZknAc9FIzVk% zo6JmFH~c{_tK!gt4+o2>)zoP{sR}!!vfRjI=13!z5}ijMFQ4a4?QIg-BE4T6!#%?d&L;`j5=a`4is>U;%@Rd~ zXC~H7eGQhhYWhMPWf9znDbYIgwud(6$W3e>$W4$~d%qoJ z+JE`1g$qJ%>b|z*xCKenmpV$0pM=Gl-Y*LT8K+P)2X#;XYEFF4mRbc~jj?DM@(1e`nL=F4Syv)TKIePQUz)bZ?Bi3@G@HO$Aps1DvDGkYF50O$_welu^cL7;vPiMGho74$;4fDqKbE{U zd1h{;LfM#Fb|Z&uH~Rm_J)R~Vy4b;1?tW_A)Iz#S_=F|~pISaVkCnQ0&u%Yz%o#|! zS-TSg87LUfFSs{tTuM3$!06ZzH&MFtG)X-l7>3)V?Txuj2HyG*5u;EY2_5vU0ujA? zHXh5G%6e3y7v?AjhyX79pnRBVr}RmPmtrxoB7lkxEzChX^(vKd+sLh?SBic=Q)5nA zdz7Mw3_iA>;T^_Kl~?1|5t%GZ;ki_+i>Q~Q1EVdKZ)$Sh3LM@ea&D~{2HOG++7*wF zAC6jW4>fa~!Vp5+$Z{<)Qxb|{unMgCv2)@%3j=7)Zc%U<^i|SAF88s!A^+Xs!OASYT%7;Jx?olg_6NFP1475N z#0s<@E~FI}#LNQ{?B1;t+N$2k*`K$Hxb%#8tRQi*Z#No0J}Pl;HWb){l7{A8(pu#@ zfE-OTvEreoz1+p`9sUI%Y{e5L-oTP_^NkgpYhZjp&ykinnW;(fu1;ttpSsgYM8ABX4dHe_HxU+%M(D=~) zYM}XUJ5guZ;=_ZcOsC`_{CiU$zN3$+x&5C`vX-V3`8&RjlBs^rf00MNYZW+jCd~7N z%{jJuUUwY(M`8$`B>K&_48!Li682ZaRknMgQ3~dnlp8C?__!P2z@=Auv;T^$yrsNy zCARmaA@^Yo2sS%2$`031-+h9KMZsIHfB>s@}>Y(z988e!`%4=EDoAQ0kbk>+lCoK60Mx9P!~I zlq~wf7kcm_NFImt3ZYlE(b3O1K^QWiFb$V^a2Jlwvm(!XYx<`i@ZMS3UwFt{;x+-v zhx{m=m;4dgvkKp5{*lfSN3o^keSpp9{hlXj%=}e_7Ou{Yiw(J@NXuh*;pL6@$HsfB zh?v+r^cp@jQ4EspC#RqpwPY(}_SS$wZ{S959`C25777&sgtNh%XTCo9VHJC-G z;;wi9{-iv+ETiY;K9qvlEc04f;ZnUP>cUL_T*ms``EtGoP^B#Q>n2dSrbAg8a>*Lg zd0EJ^=tdW~7fbcLFsqryFEcy*-8!?;n%;F+8i{eZyCDaiYxghr z$8k>L|2&-!lhvuVdk!r-kpSFl`5F5d4DJr%M4-qOy3gdmQbqF1=aBtRM7)c_Ae?$b8 zQg4c8*KQ{XJmL)1c7#0Yn0#PTMEs4-IHPjkn0!=;JdhMXqzMLeh`yOylXROP- zl#z3+fwM9l3%VN(6R77ua*uI9%hO7l7{+Hcbr(peh;afUK?B4EC09J{-u{mv)+u#? zdKVBCPt`eU@IzL)OXA`Ebu`Xp?u0m%h&X41}FNfnJ*g1!1wcbbpo%F4x!-#R9ft!8{5`Ho}04?FI#Kg zL|k`tF1t_`ywdy8(wnTut>HND(qNnq%Sq=AvvZbXnLx|mJhi!*&lwG2g|edBdVgLy zjvVTKHAx(+&P;P#2Xobo7_RttUi)Nllc}}hX>|N?-u5g7VJ-NNdwYcaOG?NK=5)}` zMtOL;o|i0mSKm(UI_7BL_^6HnVOTkuPI6y@ZLR(H?c1cr-_ouSLp{5!bx^DiKd*Yb z{K78Ci&Twup zTKm)ioN|wcYy%Qnwb)IzbH>W!;Ah5Zdm_jRY`+VRJ2 zhkspZ9hbK3iQD91A$d!0*-1i#%x81|s+SPRmD}d~<1p6!A13(!vABP2kNgqEG z?AMgl^P+iRoIY(9@_I?n1829lGvAsRnHwS~|5vD2+Zi53j<5N4wNn0{q>>jF9*bI) zL$kMXM-awNOElF>{?Jr^tOz1glbwaD-M0OKOlTeW3C!1ZyxRbB>8JDof(O&R1bh%3x#>y2~<>OXO#IIedH0Q`(&&?eo-c~ z>*Ah#3~09unym~UC-UFqqI>{dmUD$Y4@evG#ORLI*{ZM)Jl=e1it!XzY($S3V zLG!Y6fCjE>x6r@5FG1n|8ompSZaJ>9)q6jqU;XxCQk9zV(?C9+i*>w z21+KYt1gXX&0`x3E)hS7I5}snbBzox9C@Xzcr|{B8Hw;SY1$}&BoYKXH^hpjW-RgJ z-Fb}tannKCv>y~^`r|(1Q9;+sZlYf3XPSX|^gR01UFtu$B*R;$sPZdIZShRr>|b@J z;#G{EdoY+O;REEjQ}X7_YzWLO+Ey3>a_KDe1CjSe| z6arqcEZ)CX!8r(si`dqbF$uu&pnf^Np{1f*TdJ`r2;@SaZ z#hb4xlaCA@Pwqj#LlUEe5L{I$k(Zj$d3(~)u(F%&xb8={N9hKxlZIO1ABsM{Mt|)2 zJ^t9Id;?%4PfR4&Ph9B9cFK~@tG3wlFW-0fXZS_L4U*EiAA%+`h%q2^6BCC;t0iO4V=s4Qug{M|iDV@s zC7|ef-dxiR7T&Mpre!%hiUhHM%3Qxi$Lzw6&(Tvlx9QA_7LhYq<(o~=Y>3ka-zrQa zhGpfFK@)#)rtfz61w35^sN1=IFw&Oc!Nah+8@qhJ0UEGr;JplaxOGI82OVqZHsqfX ze1}r{jy;G?&}Da}a7>SCDsFDuzuseeCKof|Dz2BPsP8? zY;a)Tkr2P~0^2BeO?wnzF_Ul-ekY=-w26VnU%U3f19Z-pj&2 z4J_a|o4Dci+MO)mPQIM>kdPG1xydiR9@#8m zh27D7GF{p|a{8({Q-Pr-;#jV{2zHR>lGoFtIfIpoMo?exuQyX_A;;l0AP4!)JEM$EwMInZkj+8*IHP4vKRd zKx_l-i*>A*C@{u%ct`y~s6MWAfO{@FPIX&sg8H{GMDc{4M3%$@c8&RAlw0-R<4DO3 trJqdc$mBpWeznn?E0M$F`|3v=`3%T2A17h;rxP7$%JLd=6(2u;`(N3pt&so# literal 0 HcmV?d00001 diff --git a/docs/_static/bootstrap-2.3.2/js/bootstrap.js b/docs/_static/bootstrap-2.3.2/js/bootstrap.js new file mode 100644 index 00000000..638bb187 --- /dev/null +++ b/docs/_static/bootstrap-2.3.2/js/bootstrap.js @@ -0,0 +1,2287 @@ +/* =================================================== + * bootstrap-transition.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-alert.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.alert + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT NO CONFLICT + * ================= */ + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + /* ALERT DATA-API + * ============== */ + + $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) + +}(window.$jqTheme || window.jQuery); +/* ============================================================ + * bootstrap-button.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#buttons + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* BUTTON PUBLIC CLASS DEFINITION + * ============================== */ + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.button.defaults, options) + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + , $el = this.$element + , data = $el.data() + , val = $el.is('input') ? 'val' : 'html' + + state = state + 'Text' + data.resetText || $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d) + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons-radio"]') + + $parent && $parent + .find('.active') + .removeClass('active') + + this.$element.toggleClass('active') + } + + + /* BUTTON PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.button + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('button') + , options = typeof option == 'object' && option + if (!data) $this.data('button', (data = new Button(this, options))) + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.defaults = { + loadingText: 'loading...' + } + + $.fn.button.Constructor = Button + + + /* BUTTON NO CONFLICT + * ================== */ + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + /* BUTTON DATA-API + * =============== */ + + $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-carousel.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#carousel + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + if (this.interval) clearInterval(this.interval); + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , getActiveIndex: function () { + this.$active = this.$element.find('.item.active') + this.$items = this.$active.parent().children() + return this.$items.index(this.$active) + } + + , to: function (pos) { + var activeIndex = this.getActiveIndex() + , that = this + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activeIndex == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + , direction: direction + }) + + if ($next.hasClass('active')) return + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + this.$element.one('slid', function () { + var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) + $nextIndicator && $nextIndicator.addClass('active') + }) + } + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL NO CONFLICT + * ==================== */ + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + , slideIndex + + $target.carousel(options) + + if (slideIndex = $this.attr('data-slide-to')) { + $target.data('carousel').pause().to(slideIndex).cycle() + } + + e.preventDefault() + }) + +}(window.$jqTheme || window.jQuery); +/* ============================================================= + * bootstrap-collapse.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#collapse + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning || this.$element.hasClass('in')) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning || !this.$element.hasClass('in')) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSE PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.collapse + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSE NO CONFLICT + * ==================== */ + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + /* COLLAPSE DATA-API + * ================= */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.$jqTheme || window.jQuery); +/* ============================================================ + * bootstrap-dropdown.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=dropdown]' + , Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function (e) { + var $this = $(this) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement) { + // if mobile we we use a backdrop because click events don't delegate + $('