From d182202fc6001983541504ed323d68479086317e Mon Sep 17 00:00:00 2001 From: WuKong Date: Sat, 22 Apr 2017 13:25:07 +0200 Subject: add moonv4 Change-Id: I247af788d0b0fb961fbc85416486b241eb1d807c Signed-off-by: WuKong --- moonv4/README.md | 196 ++ moonv4/TODO | 32 + moonv4/moon_authz/LICENSE | 204 +++ moonv4/moon_authz/MANIFEST.in | 9 + moonv4/moon_authz/README.rst | 9 + moonv4/moon_authz/moon_authz/__init__.py | 6 + moonv4/moon_authz/moon_authz/__main__.py | 3 + moonv4/moon_authz/moon_authz/api/__init__.py | 0 moonv4/moon_authz/moon_authz/api/authorization.py | 445 +++++ moonv4/moon_authz/moon_authz/api/generic.py | 28 + moonv4/moon_authz/moon_authz/messenger.py | 63 + moonv4/moon_authz/moon_authz/server.py | 36 + moonv4/moon_authz/requirements.txt | 1 + moonv4/moon_authz/setup.py | 47 + moonv4/moon_db/Changelog | 12 + moonv4/moon_db/LICENSE | 204 +++ moonv4/moon_db/MANIFEST.in | 11 + moonv4/moon_db/README.rst | 9 + moonv4/moon_db/Vagrantfile | 71 + moonv4/moon_db/bin/drop_tables.sql | 18 + moonv4/moon_db/moon_db/__init__.py | 23 + moonv4/moon_db/moon_db/api/__init__.py | 0 moonv4/moon_db/moon_db/api/keystone.py | 106 ++ moonv4/moon_db/moon_db/api/managers.py | 15 + moonv4/moon_db/moon_db/api/model.py | 141 ++ moonv4/moon_db/moon_db/api/pdp.py | 48 + moonv4/moon_db/moon_db/api/policy.py | 237 +++ moonv4/moon_db/moon_db/api/tenants.py | 137 ++ moonv4/moon_db/moon_db/backends/__init__.py | 97 + moonv4/moon_db/moon_db/backends/flat.py | 89 + moonv4/moon_db/moon_db/backends/memory.py | 60 + moonv4/moon_db/moon_db/backends/sql.py | 1877 ++++++++++++++++++++ moonv4/moon_db/moon_db/core.py | 303 ++++ moonv4/moon_db/moon_db/db_manager.py | 47 + moonv4/moon_db/moon_db/exception.py | 410 +++++ moonv4/moon_db/moon_db/migrate_repo/__init__.py | 0 .../moon_db/migrate_repo/versions/001_moon.py | 216 +++ .../moon_db/migrate_repo/versions/__init__.py | 0 moonv4/moon_db/requirements.txt | 5 + moonv4/moon_db/setup.py | 53 + moonv4/moon_db/tests/configure_db.sh | 9 + moonv4/moon_db/tests/test_intraextension.py | 44 + moonv4/moon_db/tests/test_tenant.py | 86 + moonv4/moon_gui/.gitignore | 4 + moonv4/moon_gui/.jshintrc | 61 + moonv4/moon_gui/delivery/assets/css/main.css | 10 + .../assets/fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20335 bytes .../assets/fonts/glyphicons-halflings-regular.svg | 229 +++ .../assets/fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41280 bytes .../assets/fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23320 bytes moonv4/moon_gui/delivery/assets/i18n/en.json | 1266 +++++++++++++ moonv4/moon_gui/delivery/assets/i18n/fr.json | 1266 +++++++++++++ .../moon_gui/delivery/assets/img/ajax-loader.gif | Bin 0 -> 673 bytes .../moon_gui/delivery/assets/img/ajax-waiting.gif | Bin 0 -> 10819 bytes moonv4/moon_gui/delivery/assets/img/arrow-link.gif | Bin 0 -> 87 bytes moonv4/moon_gui/delivery/assets/img/favicon.ico | Bin 0 -> 318 bytes .../delivery/assets/img/logo-openstack.png | Bin 0 -> 3180 bytes .../moon_gui/delivery/assets/img/logo-orange.gif | Bin 0 -> 981 bytes .../html/authentication/authentication.tpl.html | 1 + .../moon_gui/delivery/html/common/404/404.tpl.html | 1 + .../common/compatibility/compatibility.tpl.html | 1 + .../delivery/html/common/footer/footer.tpl.html | 1 + .../delivery/html/common/header/header.tpl.html | 1 + .../delivery/html/common/loader/loader.tpl.html | 1 + .../delivery/html/common/waiting/waiting.tpl.html | 1 + .../delivery/html/dashboard/dashboard.tpl.html | 1 + moonv4/moon_gui/delivery/html/logs/logs.tpl.html | 1 + .../delivery/html/model/action/model-add.tpl.html | 1 + .../html/model/action/model-delete.tpl.html | 1 + .../delivery/html/model/action/model-view.tpl.html | 1 + .../model/edit/metadata/metadata-edit.tpl.html | 1 + .../model/edit/metadata/metadata-list.tpl.html | 82 + .../action/mapping/metarules-add.tpl.html | 1 + .../action/mapping/metarules-map.tpl.html | 1 + .../action/mapping/metarules-unmap.tpl.html | 1 + .../metarules/action/metarules-edit-basic.tpl.html | 1 + .../edit/metarules/action/metarules-edit.tpl.html | 1 + .../model/edit/metarules/metarules-list.tpl.html | 1 + .../html/model/edit/model-edit-basic.tpl.html | 1 + .../delivery/html/model/edit/model-edit.tpl.html | 4 + .../delivery/html/model/model-list.tpl.html | 6 + .../delivery/html/pdp/action/pdp-add.tpl.html | 1 + .../delivery/html/pdp/action/pdp-delete.tpl.html | 1 + .../delivery/html/pdp/edit/pdp-edit-basic.tpl.html | 1 + .../delivery/html/pdp/edit/pdp-edit.tpl.html | 1 + .../moon_gui/delivery/html/pdp/pdp-list.tpl.html | 1 + .../html/policy/action/mapping/policy-map.tpl.html | 1 + .../policy/action/mapping/policy-unmap.tpl.html | 1 + .../html/policy/action/policy-add.tpl.html | 1 + .../html/policy/action/policy-delete.tpl.html | 1 + .../assignments/assignments-list.tpl.html | 1 + .../policy/edit/parameter/data/data-list.tpl.html | 113 ++ .../parameter/perimeter/perimeter-list.tpl.html | 114 ++ .../edit/parameter/rules/rules-list.tpl.html | 1 + .../html/policy/edit/policy-edit-basic.tpl.html | 1 + .../delivery/html/policy/edit/policy-edit.tpl.html | 13 + .../delivery/html/policy/policy-list.tpl.html | 1 + .../html/policy/policy-mapped-list.tpl.html | 1 + .../project/action/mapping/project-map.tpl.html | 1 + .../project/action/mapping/project-unmap.tpl.html | 1 + .../html/project/action/project-add.tpl.html | 1 + .../html/project/action/project-delete.tpl.html | 1 + .../html/project/action/project-view.tpl.html | 1 + .../delivery/html/project/project-list.tpl.html | 1 + moonv4/moon_gui/delivery/index.html | 34 + moonv4/moon_gui/delivery/js/app.js | 3 + moonv4/moon_gui/delivery/js/modules.js | 19 + moonv4/moon_gui/delivery/version.json | 1 + moonv4/moon_gui/gulpfile.js | 213 +++ moonv4/moon_gui/package.json | 54 + moonv4/moon_gui/readme.md | 60 + .../authentication/authentication.controller.js | 54 + .../app/authentication/authentication.tpl.html | 28 + moonv4/moon_gui/static/app/common/404/404.tpl.html | 3 + .../common/compatibility/compatibility.tpl.html | 26 + .../static/app/common/footer/footer.controller.js | 54 + .../static/app/common/footer/footer.tpl.html | 7 + .../static/app/common/header/header.controller.js | 53 + .../static/app/common/header/header.tpl.html | 50 + .../static/app/common/loader/loader.dir.js | 19 + .../static/app/common/loader/loader.tpl.html | 1 + .../static/app/common/waiting/waiting.tpl.html | 15 + .../static/app/dashboard/dashboard.tpl.html | 14 + moonv4/moon_gui/static/app/logs/logs.controller.js | 16 + moonv4/moon_gui/static/app/logs/logs.tpl.html | 3 + .../static/app/model/action/model-add.tpl.html | 66 + .../static/app/model/action/model-delete.tpl.html | 39 + .../static/app/model/action/model-view.tpl.html | 41 + .../app/model/action/model.controller.add.js | 71 + .../app/model/action/model.controller.delete.js | 72 + .../app/model/action/model.controller.view.js | 53 + .../app/model/edit/metadata/metadata-edit.tpl.html | 99 ++ .../app/model/edit/metadata/metadata-list.tpl.html | 333 ++++ .../app/model/edit/metadata/metadata.edit.dir.js | 330 ++++ .../app/model/edit/metadata/metadata.list.dir.js | 367 ++++ .../action/mapping/metarules-add.tpl.html | 50 + .../action/mapping/metarules-map.tpl.html | 102 ++ .../action/mapping/metarules-unmap.tpl.html | 35 + .../action/mapping/metarules.controller.add.js | 99 ++ .../action/mapping/metarules.map.controller.js | 213 +++ .../action/mapping/metarules.unmap.controller.js | 74 + .../metarules/action/metarules-edit-basic.tpl.html | 67 + .../edit/metarules/action/metarules-edit.tpl.html | 62 + .../metarules/action/metarules.controller.edit.js | 49 + .../metarules/action/metarules.edit.basic.dir.js | 98 + .../model/edit/metarules/metarules-list.tpl.html | 149 ++ .../app/model/edit/metarules/metarules.list.dir.js | 237 +++ .../app/model/edit/model-edit-basic.tpl.html | 65 + .../static/app/model/edit/model-edit.tpl.html | 66 + .../static/app/model/edit/model.controller.edit.js | 55 + .../static/app/model/edit/model.edit.basic.dir.js | 97 + .../moon_gui/static/app/model/model-list.tpl.html | 123 ++ .../static/app/model/model.controller.list.js | 195 ++ moonv4/moon_gui/static/app/moon.constants.js | 86 + moonv4/moon_gui/static/app/moon.module.js | 362 ++++ .../static/app/pdp/action/pdp-add.tpl.html | 88 + .../static/app/pdp/action/pdp-delete.tpl.html | 35 + .../static/app/pdp/action/pdp.controller.add.js | 108 ++ .../static/app/pdp/action/pdp.controller.delete.js | 66 + .../static/app/pdp/edit/pdp-edit-basic.tpl.html | 65 + .../moon_gui/static/app/pdp/edit/pdp-edit.tpl.html | 56 + .../static/app/pdp/edit/pdp.controller.edit.js | 50 + .../static/app/pdp/edit/pdp.edit.basic.dir.js | 97 + moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html | 133 ++ .../moon_gui/static/app/pdp/pdp.controller.list.js | 287 +++ .../app/policy/action/mapping/policy-map.tpl.html | 64 + .../policy/action/mapping/policy-unmap.tpl.html | 33 + .../policy/action/mapping/policy.controller.map.js | 106 ++ .../action/mapping/policy.controller.unmap.js | 74 + .../static/app/policy/action/policy-add.tpl.html | 113 ++ .../app/policy/action/policy-delete.tpl.html | 40 + .../app/policy/action/policy.controller.add.js | 113 ++ .../app/policy/action/policy.controller.delete.js | 69 + .../assignments/assignments-list.tpl.html | 323 ++++ .../parameter/assignments/assignments.list.dir.js | 500 ++++++ .../policy/edit/parameter/data/data-list.tpl.html | 349 ++++ .../policy/edit/parameter/data/data.edit.dir.js | 330 ++++ .../policy/edit/parameter/data/data.list.dir.js | 401 +++++ .../parameter/perimeter/perimeter-list.tpl.html | 320 ++++ .../edit/parameter/perimeter/perimeter.list.dir.js | 358 ++++ .../edit/parameter/rules/rules-list.tpl.html | 102 ++ .../policy/edit/parameter/rules/rules.list.dir.js | 254 +++ .../app/policy/edit/policy-edit-basic.tpl.html | 89 + .../static/app/policy/edit/policy-edit.tpl.html | 202 +++ .../app/policy/edit/policy.controller.edit.js | 74 + .../app/policy/edit/policy.edit.basic.dir.js | 134 ++ .../static/app/policy/policy-list.tpl.html | 131 ++ .../static/app/policy/policy-mapped-list.tpl.html | 88 + .../static/app/policy/policy.controller.list.js | 175 ++ .../static/app/policy/policy.mapped.list.dir.js | 203 +++ .../project/action/mapping/project-map.tpl.html | 62 + .../project/action/mapping/project-unmap.tpl.html | 33 + .../action/mapping/project.controller.map.js | 107 ++ .../action/mapping/project.controller.unmap.js | 74 + .../static/app/project/action/project-add.tpl.html | 89 + .../app/project/action/project-delete.tpl.html | 45 + .../app/project/action/project-view.tpl.html | 194 ++ .../app/project/action/project.controller.add.js | 78 + .../project/action/project.controller.delete.js | 134 ++ .../app/project/action/project.controller.view.js | 216 +++ .../static/app/project/project-list.tpl.html | 157 ++ .../static/app/project/project.controller.list.js | 310 ++++ .../static/app/services/gui/alert.service.js | 39 + .../static/app/services/gui/browser.service.js | 47 + .../static/app/services/gui/form.service.js | 47 + .../static/app/services/gui/menu.service.js | 49 + .../app/services/gui/security.pipeline.service.js | 29 + .../static/app/services/gui/util.service.js | 66 + .../static/app/services/gui/version.service.js | 27 + .../app/services/moon/model/model.service.js | 105 ++ .../static/app/services/moon/pdp.service.js | 128 ++ .../moon/policy/parameters/assignements.service.js | 96 + .../moon/policy/parameters/data.service.js | 196 ++ .../moon/policy/parameters/perimeter.service.js | 419 +++++ .../moon/policy/parameters/rule.service.js | 49 + .../app/services/moon/policy/policy.service.js | 108 ++ .../app/services/moon/rule/metadata.service.js | 354 ++++ .../app/services/moon/rule/metarule.service.js | 208 +++ .../app/services/partner/authentication.service.js | 106 ++ .../static/app/services/partner/nova.service.js | 35 + .../static/app/services/partner/project.service.js | 60 + moonv4/moon_gui/static/favicon.ico | Bin 0 -> 318 bytes moonv4/moon_gui/static/i18n/en.json | 1266 +++++++++++++ moonv4/moon_gui/static/i18n/fr.json | 1266 +++++++++++++ moonv4/moon_gui/static/img/ajax-loader.gif | Bin 0 -> 673 bytes moonv4/moon_gui/static/img/ajax-waiting.gif | Bin 0 -> 10819 bytes moonv4/moon_gui/static/img/arrow-link.gif | Bin 0 -> 87 bytes moonv4/moon_gui/static/img/et.jpg | Bin 0 -> 31641 bytes moonv4/moon_gui/static/img/logo-openstack.png | Bin 0 -> 3180 bytes moonv4/moon_gui/static/img/logo-orange.gif | Bin 0 -> 981 bytes moonv4/moon_gui/static/styles/main.css | 169 ++ moonv4/moon_gui/static/version.json | 3 + moonv4/moon_gui/templates/index.html | 31 + moonv4/moon_interface/.cache/v/cache/lastfailed | 1 + moonv4/moon_interface/LICENSE | 204 +++ moonv4/moon_interface/MANIFEST.in | 9 + moonv4/moon_interface/Makefile | 12 + moonv4/moon_interface/README.rst | 9 + moonv4/moon_interface/moon_interface/__init__.py | 6 + moonv4/moon_interface/moon_interface/__main__.py | 3 + .../moon_interface/moon_interface/api/__init__.py | 0 .../moon_interface/api/assignments.py | 261 +++ moonv4/moon_interface/moon_interface/api/authz.py | 66 + moonv4/moon_interface/moon_interface/api/data.py | 261 +++ .../moon_interface/moon_interface/api/generic.py | 153 ++ .../moon_interface/moon_interface/api/meta_data.py | 206 +++ .../moon_interface/api/meta_rules.py | 140 ++ moonv4/moon_interface/moon_interface/api/models.py | 103 ++ moonv4/moon_interface/moon_interface/api/pdp.py | 108 ++ .../moon_interface/moon_interface/api/perimeter.py | 314 ++++ .../moon_interface/moon_interface/api/policies.py | 108 ++ moonv4/moon_interface/moon_interface/api/rules.py | 95 + .../moon_interface/moon_interface/http_server.py | 173 ++ moonv4/moon_interface/moon_interface/server.py | 26 + moonv4/moon_interface/moon_interface/tools.py | 99 ++ moonv4/moon_interface/requirements.txt | 7 + moonv4/moon_interface/setup.py | 47 + moonv4/moon_interface/tests/apitests/README.md | 33 + .../tests/apitests/populate_default_values.py | 149 ++ .../moon_interface/tests/apitests/scenario/mls.py | 44 + .../moon_interface/tests/apitests/scenario/rbac.py | 32 + .../tests/apitests/scenario/rbac_mls.py | 50 + .../moon_interface/tests/apitests/test_models.py | 37 + moonv4/moon_interface/tests/apitests/test_pdp.py | 16 + .../moon_interface/tests/apitests/test_policies.py | 154 ++ .../tests/apitests/utils/__init__.py | 0 .../moon_interface/tests/apitests/utils/models.py | 260 +++ moonv4/moon_interface/tests/apitests/utils/pdp.py | 145 ++ .../tests/apitests/utils/policies.py | 581 ++++++ moonv4/moon_interface/tools/api2rst.py | 145 ++ moonv4/moon_interface/tools/get_keystone_token.py | 72 + moonv4/moon_interface/tools/run.sh | 5 + moonv4/moon_manager/LICENSE | 204 +++ moonv4/moon_manager/MANIFEST.in | 9 + moonv4/moon_manager/README.rst | 9 + moonv4/moon_manager/moon_manager/__init__.py | 6 + moonv4/moon_manager/moon_manager/__main__.py | 3 + moonv4/moon_manager/moon_manager/api/__init__.py | 0 moonv4/moon_manager/moon_manager/api/generic.py | 28 + moonv4/moon_manager/moon_manager/api/models.py | 199 +++ moonv4/moon_manager/moon_manager/api/pdp.py | 68 + moonv4/moon_manager/moon_manager/api/policies.py | 414 +++++ moonv4/moon_manager/moon_manager/messenger.py | 73 + moonv4/moon_manager/moon_manager/server.py | 25 + moonv4/moon_manager/requirements.txt | 5 + moonv4/moon_manager/setup.py | 47 + moonv4/moon_secrouter/LICENSE | 204 +++ moonv4/moon_secrouter/MANIFEST.in | 9 + moonv4/moon_secrouter/README.rst | 9 + moonv4/moon_secrouter/doc/api-moon-secrouter.pdf | Bin 0 -> 195778 bytes moonv4/moon_secrouter/doc/api.pdf | Bin 0 -> 195377 bytes moonv4/moon_secrouter/moon_secrouter/__init__.py | 6 + moonv4/moon_secrouter/moon_secrouter/__main__.py | 3 + .../moon_secrouter/moon_secrouter/api/__init__.py | 0 .../moon_secrouter/moon_secrouter/api/generic.py | 46 + moonv4/moon_secrouter/moon_secrouter/api/route.py | 254 +++ moonv4/moon_secrouter/moon_secrouter/messenger.py | 61 + moonv4/moon_secrouter/moon_secrouter/server.py | 59 + moonv4/moon_secrouter/requirements.txt | 5 + moonv4/moon_secrouter/setup.py | 47 + moonv4/moon_secrouter/tests/moon_db-0.1.0.tar.gz | Bin 0 -> 21423 bytes .../moon_secrouter/tests/moon_policy-0.1.0.tar.gz | Bin 0 -> 8640 bytes moonv4/moon_utilities/LICENSE | 204 +++ moonv4/moon_utilities/MANIFEST.in | 9 + moonv4/moon_utilities/README.rst | 9 + moonv4/moon_utilities/moon_utilities/__init__.py | 6 + moonv4/moon_utilities/moon_utilities/api.py | 28 + moonv4/moon_utilities/moon_utilities/exceptions.py | 505 ++++++ moonv4/moon_utilities/moon_utilities/misc.py | 47 + moonv4/moon_utilities/moon_utilities/options.py | 300 ++++ .../moon_utilities/security_functions.py | 405 +++++ moonv4/moon_utilities/requirements.txt | 6 + moonv4/moon_utilities/setup.py | 41 + moonv4/templates/docker/keystone/Dockerfile | 27 + moonv4/templates/docker/keystone/README.md | 8 + moonv4/templates/docker/keystone/run.sh | 128 ++ 316 files changed, 32779 insertions(+) create mode 100644 moonv4/README.md create mode 100644 moonv4/TODO create mode 100644 moonv4/moon_authz/LICENSE create mode 100644 moonv4/moon_authz/MANIFEST.in create mode 100644 moonv4/moon_authz/README.rst create mode 100644 moonv4/moon_authz/moon_authz/__init__.py create mode 100644 moonv4/moon_authz/moon_authz/__main__.py create mode 100644 moonv4/moon_authz/moon_authz/api/__init__.py create mode 100644 moonv4/moon_authz/moon_authz/api/authorization.py create mode 100644 moonv4/moon_authz/moon_authz/api/generic.py create mode 100644 moonv4/moon_authz/moon_authz/messenger.py create mode 100644 moonv4/moon_authz/moon_authz/server.py create mode 100644 moonv4/moon_authz/requirements.txt create mode 100644 moonv4/moon_authz/setup.py create mode 100644 moonv4/moon_db/Changelog create mode 100644 moonv4/moon_db/LICENSE create mode 100644 moonv4/moon_db/MANIFEST.in create mode 100644 moonv4/moon_db/README.rst create mode 100644 moonv4/moon_db/Vagrantfile create mode 100644 moonv4/moon_db/bin/drop_tables.sql create mode 100644 moonv4/moon_db/moon_db/__init__.py create mode 100644 moonv4/moon_db/moon_db/api/__init__.py create mode 100644 moonv4/moon_db/moon_db/api/keystone.py create mode 100644 moonv4/moon_db/moon_db/api/managers.py create mode 100644 moonv4/moon_db/moon_db/api/model.py create mode 100644 moonv4/moon_db/moon_db/api/pdp.py create mode 100644 moonv4/moon_db/moon_db/api/policy.py create mode 100644 moonv4/moon_db/moon_db/api/tenants.py create mode 100644 moonv4/moon_db/moon_db/backends/__init__.py create mode 100644 moonv4/moon_db/moon_db/backends/flat.py create mode 100644 moonv4/moon_db/moon_db/backends/memory.py create mode 100644 moonv4/moon_db/moon_db/backends/sql.py create mode 100644 moonv4/moon_db/moon_db/core.py create mode 100644 moonv4/moon_db/moon_db/db_manager.py create mode 100644 moonv4/moon_db/moon_db/exception.py create mode 100644 moonv4/moon_db/moon_db/migrate_repo/__init__.py create mode 100644 moonv4/moon_db/moon_db/migrate_repo/versions/001_moon.py create mode 100644 moonv4/moon_db/moon_db/migrate_repo/versions/__init__.py create mode 100644 moonv4/moon_db/requirements.txt create mode 100644 moonv4/moon_db/setup.py create mode 100644 moonv4/moon_db/tests/configure_db.sh create mode 100644 moonv4/moon_db/tests/test_intraextension.py create mode 100644 moonv4/moon_db/tests/test_tenant.py create mode 100644 moonv4/moon_gui/.gitignore create mode 100644 moonv4/moon_gui/.jshintrc create mode 100644 moonv4/moon_gui/delivery/assets/css/main.css create mode 100644 moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot create mode 100644 moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg create mode 100644 moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf create mode 100644 moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff create mode 100755 moonv4/moon_gui/delivery/assets/i18n/en.json create mode 100755 moonv4/moon_gui/delivery/assets/i18n/fr.json create mode 100755 moonv4/moon_gui/delivery/assets/img/ajax-loader.gif create mode 100755 moonv4/moon_gui/delivery/assets/img/ajax-waiting.gif create mode 100755 moonv4/moon_gui/delivery/assets/img/arrow-link.gif create mode 100755 moonv4/moon_gui/delivery/assets/img/favicon.ico create mode 100755 moonv4/moon_gui/delivery/assets/img/logo-openstack.png create mode 100755 moonv4/moon_gui/delivery/assets/img/logo-orange.gif create mode 100644 moonv4/moon_gui/delivery/html/authentication/authentication.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/common/404/404.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/common/footer/footer.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/common/header/header.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/common/loader/loader.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/common/waiting/waiting.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/dashboard/dashboard.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/logs/logs.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/action/model-add.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/action/model-delete.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/action/model-view.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/edit/model-edit.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/model/model-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/pdp/pdp-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/action/policy-add.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/action/policy-delete.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/policy-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/project/action/project-add.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/project/action/project-delete.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/project/action/project-view.tpl.html create mode 100644 moonv4/moon_gui/delivery/html/project/project-list.tpl.html create mode 100644 moonv4/moon_gui/delivery/index.html create mode 100644 moonv4/moon_gui/delivery/js/app.js create mode 100644 moonv4/moon_gui/delivery/js/modules.js create mode 100755 moonv4/moon_gui/delivery/version.json create mode 100644 moonv4/moon_gui/gulpfile.js create mode 100644 moonv4/moon_gui/package.json create mode 100644 moonv4/moon_gui/readme.md create mode 100644 moonv4/moon_gui/static/app/authentication/authentication.controller.js create mode 100644 moonv4/moon_gui/static/app/authentication/authentication.tpl.html create mode 100644 moonv4/moon_gui/static/app/common/404/404.tpl.html create mode 100644 moonv4/moon_gui/static/app/common/compatibility/compatibility.tpl.html create mode 100644 moonv4/moon_gui/static/app/common/footer/footer.controller.js create mode 100644 moonv4/moon_gui/static/app/common/footer/footer.tpl.html create mode 100644 moonv4/moon_gui/static/app/common/header/header.controller.js create mode 100644 moonv4/moon_gui/static/app/common/header/header.tpl.html create mode 100644 moonv4/moon_gui/static/app/common/loader/loader.dir.js create mode 100644 moonv4/moon_gui/static/app/common/loader/loader.tpl.html create mode 100644 moonv4/moon_gui/static/app/common/waiting/waiting.tpl.html create mode 100644 moonv4/moon_gui/static/app/dashboard/dashboard.tpl.html create mode 100644 moonv4/moon_gui/static/app/logs/logs.controller.js create mode 100644 moonv4/moon_gui/static/app/logs/logs.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/action/model-add.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/action/model-delete.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/action/model-view.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/action/model.controller.add.js create mode 100644 moonv4/moon_gui/static/app/model/action/model.controller.delete.js create mode 100644 moonv4/moon_gui/static/app/model/action/model.controller.view.js create mode 100644 moonv4/moon_gui/static/app/model/edit/metadata/metadata-edit.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/metadata/metadata-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/metadata/metadata.edit.dir.js create mode 100644 moonv4/moon_gui/static/app/model/edit/metadata/metadata.list.dir.js create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-add.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-map.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules-unmap.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.controller.add.js create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.map.controller.js create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/mapping/metarules.unmap.controller.js create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit-basic.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/metarules-edit.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.controller.edit.js create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/action/metarules.edit.basic.dir.js create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/metarules-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/metarules/metarules.list.dir.js create mode 100644 moonv4/moon_gui/static/app/model/edit/model-edit-basic.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/model-edit.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/edit/model.controller.edit.js create mode 100644 moonv4/moon_gui/static/app/model/edit/model.edit.basic.dir.js create mode 100644 moonv4/moon_gui/static/app/model/model-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/model/model.controller.list.js create mode 100644 moonv4/moon_gui/static/app/moon.constants.js create mode 100644 moonv4/moon_gui/static/app/moon.module.js create mode 100644 moonv4/moon_gui/static/app/pdp/action/pdp-add.tpl.html create mode 100644 moonv4/moon_gui/static/app/pdp/action/pdp-delete.tpl.html create mode 100644 moonv4/moon_gui/static/app/pdp/action/pdp.controller.add.js create mode 100644 moonv4/moon_gui/static/app/pdp/action/pdp.controller.delete.js create mode 100644 moonv4/moon_gui/static/app/pdp/edit/pdp-edit-basic.tpl.html create mode 100644 moonv4/moon_gui/static/app/pdp/edit/pdp-edit.tpl.html create mode 100644 moonv4/moon_gui/static/app/pdp/edit/pdp.controller.edit.js create mode 100644 moonv4/moon_gui/static/app/pdp/edit/pdp.edit.basic.dir.js create mode 100644 moonv4/moon_gui/static/app/pdp/pdp-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/pdp/pdp.controller.list.js create mode 100644 moonv4/moon_gui/static/app/policy/action/mapping/policy-map.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/action/mapping/policy-unmap.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.map.js create mode 100644 moonv4/moon_gui/static/app/policy/action/mapping/policy.controller.unmap.js create mode 100644 moonv4/moon_gui/static/app/policy/action/policy-add.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/action/policy-delete.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/action/policy.controller.add.js create mode 100644 moonv4/moon_gui/static/app/policy/action/policy.controller.delete.js create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/assignments/assignments.list.dir.js create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/data/data-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/data/data.edit.dir.js create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/data/data.list.dir.js create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/perimeter/perimeter.list.dir.js create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/edit/parameter/rules/rules.list.dir.js create mode 100644 moonv4/moon_gui/static/app/policy/edit/policy-edit-basic.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/edit/policy-edit.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/edit/policy.controller.edit.js create mode 100644 moonv4/moon_gui/static/app/policy/edit/policy.edit.basic.dir.js create mode 100644 moonv4/moon_gui/static/app/policy/policy-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/policy-mapped-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/policy/policy.controller.list.js create mode 100644 moonv4/moon_gui/static/app/policy/policy.mapped.list.dir.js create mode 100644 moonv4/moon_gui/static/app/project/action/mapping/project-map.tpl.html create mode 100644 moonv4/moon_gui/static/app/project/action/mapping/project-unmap.tpl.html create mode 100644 moonv4/moon_gui/static/app/project/action/mapping/project.controller.map.js create mode 100644 moonv4/moon_gui/static/app/project/action/mapping/project.controller.unmap.js create mode 100644 moonv4/moon_gui/static/app/project/action/project-add.tpl.html create mode 100644 moonv4/moon_gui/static/app/project/action/project-delete.tpl.html create mode 100644 moonv4/moon_gui/static/app/project/action/project-view.tpl.html create mode 100644 moonv4/moon_gui/static/app/project/action/project.controller.add.js create mode 100644 moonv4/moon_gui/static/app/project/action/project.controller.delete.js create mode 100644 moonv4/moon_gui/static/app/project/action/project.controller.view.js create mode 100644 moonv4/moon_gui/static/app/project/project-list.tpl.html create mode 100644 moonv4/moon_gui/static/app/project/project.controller.list.js create mode 100644 moonv4/moon_gui/static/app/services/gui/alert.service.js create mode 100644 moonv4/moon_gui/static/app/services/gui/browser.service.js create mode 100644 moonv4/moon_gui/static/app/services/gui/form.service.js create mode 100644 moonv4/moon_gui/static/app/services/gui/menu.service.js create mode 100644 moonv4/moon_gui/static/app/services/gui/security.pipeline.service.js create mode 100644 moonv4/moon_gui/static/app/services/gui/util.service.js create mode 100644 moonv4/moon_gui/static/app/services/gui/version.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/model/model.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/pdp.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/policy/parameters/assignements.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/policy/parameters/data.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/policy/parameters/perimeter.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/policy/parameters/rule.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/policy/policy.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/rule/metadata.service.js create mode 100644 moonv4/moon_gui/static/app/services/moon/rule/metarule.service.js create mode 100644 moonv4/moon_gui/static/app/services/partner/authentication.service.js create mode 100644 moonv4/moon_gui/static/app/services/partner/nova.service.js create mode 100644 moonv4/moon_gui/static/app/services/partner/project.service.js create mode 100755 moonv4/moon_gui/static/favicon.ico create mode 100755 moonv4/moon_gui/static/i18n/en.json create mode 100755 moonv4/moon_gui/static/i18n/fr.json create mode 100755 moonv4/moon_gui/static/img/ajax-loader.gif create mode 100755 moonv4/moon_gui/static/img/ajax-waiting.gif create mode 100755 moonv4/moon_gui/static/img/arrow-link.gif create mode 100644 moonv4/moon_gui/static/img/et.jpg create mode 100755 moonv4/moon_gui/static/img/logo-openstack.png create mode 100755 moonv4/moon_gui/static/img/logo-orange.gif create mode 100644 moonv4/moon_gui/static/styles/main.css create mode 100755 moonv4/moon_gui/static/version.json create mode 100644 moonv4/moon_gui/templates/index.html create mode 100644 moonv4/moon_interface/.cache/v/cache/lastfailed create mode 100644 moonv4/moon_interface/LICENSE create mode 100644 moonv4/moon_interface/MANIFEST.in create mode 100644 moonv4/moon_interface/Makefile create mode 100644 moonv4/moon_interface/README.rst create mode 100644 moonv4/moon_interface/moon_interface/__init__.py create mode 100644 moonv4/moon_interface/moon_interface/__main__.py create mode 100644 moonv4/moon_interface/moon_interface/api/__init__.py create mode 100644 moonv4/moon_interface/moon_interface/api/assignments.py create mode 100644 moonv4/moon_interface/moon_interface/api/authz.py create mode 100644 moonv4/moon_interface/moon_interface/api/data.py create mode 100644 moonv4/moon_interface/moon_interface/api/generic.py create mode 100644 moonv4/moon_interface/moon_interface/api/meta_data.py create mode 100644 moonv4/moon_interface/moon_interface/api/meta_rules.py create mode 100644 moonv4/moon_interface/moon_interface/api/models.py create mode 100644 moonv4/moon_interface/moon_interface/api/pdp.py create mode 100644 moonv4/moon_interface/moon_interface/api/perimeter.py create mode 100644 moonv4/moon_interface/moon_interface/api/policies.py create mode 100644 moonv4/moon_interface/moon_interface/api/rules.py create mode 100644 moonv4/moon_interface/moon_interface/http_server.py create mode 100644 moonv4/moon_interface/moon_interface/server.py create mode 100644 moonv4/moon_interface/moon_interface/tools.py create mode 100644 moonv4/moon_interface/requirements.txt create mode 100644 moonv4/moon_interface/setup.py create mode 100644 moonv4/moon_interface/tests/apitests/README.md create mode 100644 moonv4/moon_interface/tests/apitests/populate_default_values.py create mode 100644 moonv4/moon_interface/tests/apitests/scenario/mls.py create mode 100644 moonv4/moon_interface/tests/apitests/scenario/rbac.py create mode 100644 moonv4/moon_interface/tests/apitests/scenario/rbac_mls.py create mode 100644 moonv4/moon_interface/tests/apitests/test_models.py create mode 100644 moonv4/moon_interface/tests/apitests/test_pdp.py create mode 100644 moonv4/moon_interface/tests/apitests/test_policies.py create mode 100644 moonv4/moon_interface/tests/apitests/utils/__init__.py create mode 100644 moonv4/moon_interface/tests/apitests/utils/models.py create mode 100644 moonv4/moon_interface/tests/apitests/utils/pdp.py create mode 100644 moonv4/moon_interface/tests/apitests/utils/policies.py create mode 100644 moonv4/moon_interface/tools/api2rst.py create mode 100644 moonv4/moon_interface/tools/get_keystone_token.py create mode 100644 moonv4/moon_interface/tools/run.sh create mode 100644 moonv4/moon_manager/LICENSE create mode 100644 moonv4/moon_manager/MANIFEST.in create mode 100644 moonv4/moon_manager/README.rst create mode 100644 moonv4/moon_manager/moon_manager/__init__.py create mode 100644 moonv4/moon_manager/moon_manager/__main__.py create mode 100644 moonv4/moon_manager/moon_manager/api/__init__.py create mode 100644 moonv4/moon_manager/moon_manager/api/generic.py create mode 100644 moonv4/moon_manager/moon_manager/api/models.py create mode 100644 moonv4/moon_manager/moon_manager/api/pdp.py create mode 100644 moonv4/moon_manager/moon_manager/api/policies.py create mode 100644 moonv4/moon_manager/moon_manager/messenger.py create mode 100644 moonv4/moon_manager/moon_manager/server.py create mode 100644 moonv4/moon_manager/requirements.txt create mode 100644 moonv4/moon_manager/setup.py create mode 100644 moonv4/moon_secrouter/LICENSE create mode 100644 moonv4/moon_secrouter/MANIFEST.in create mode 100644 moonv4/moon_secrouter/README.rst create mode 100644 moonv4/moon_secrouter/doc/api-moon-secrouter.pdf create mode 100644 moonv4/moon_secrouter/doc/api.pdf create mode 100644 moonv4/moon_secrouter/moon_secrouter/__init__.py create mode 100644 moonv4/moon_secrouter/moon_secrouter/__main__.py create mode 100644 moonv4/moon_secrouter/moon_secrouter/api/__init__.py create mode 100644 moonv4/moon_secrouter/moon_secrouter/api/generic.py create mode 100644 moonv4/moon_secrouter/moon_secrouter/api/route.py create mode 100644 moonv4/moon_secrouter/moon_secrouter/messenger.py create mode 100644 moonv4/moon_secrouter/moon_secrouter/server.py create mode 100644 moonv4/moon_secrouter/requirements.txt create mode 100644 moonv4/moon_secrouter/setup.py create mode 100644 moonv4/moon_secrouter/tests/moon_db-0.1.0.tar.gz create mode 100644 moonv4/moon_secrouter/tests/moon_policy-0.1.0.tar.gz create mode 100644 moonv4/moon_utilities/LICENSE create mode 100644 moonv4/moon_utilities/MANIFEST.in create mode 100644 moonv4/moon_utilities/README.rst create mode 100644 moonv4/moon_utilities/moon_utilities/__init__.py create mode 100644 moonv4/moon_utilities/moon_utilities/api.py create mode 100644 moonv4/moon_utilities/moon_utilities/exceptions.py create mode 100644 moonv4/moon_utilities/moon_utilities/misc.py create mode 100644 moonv4/moon_utilities/moon_utilities/options.py create mode 100644 moonv4/moon_utilities/moon_utilities/security_functions.py create mode 100644 moonv4/moon_utilities/requirements.txt create mode 100644 moonv4/moon_utilities/setup.py create mode 100644 moonv4/templates/docker/keystone/Dockerfile create mode 100644 moonv4/templates/docker/keystone/README.md create mode 100644 moonv4/templates/docker/keystone/run.sh diff --git a/moonv4/README.md b/moonv4/README.md new file mode 100644 index 00000000..89e4729b --- /dev/null +++ b/moonv4/README.md @@ -0,0 +1,196 @@ +# Modules for the Moon project + +This directory contains all the modules for MoonV4 + + +## Usage + +### Prerequist + +- `sudo apt install python3-dev python3-pip` +- `sudo pip3 install pip --upgrade` +- `sudo apt -y install docker-engine` ([Get Docker](https://docs.docker.com/engine/installation/)) +- `echo 127.0.0.1 messenger db keystone | sudo tee -a /etc/hosts` +- modify moon orchestrator dist path in moon_orchestrator/conf/moon.conf +- `sudo ln -s $(pwd)/conf /etc/moon` + +### Get the code + +```bash +git clone https://github.com/rebirthmonkey/moonv4.git +cd moonv4 +export MOON_HOME=$(pwd) +``` + +### Create an OpenStack environment + +```bash +cd $MOON_HOME/templates/docker/keystone +# Check the proxy settings in Dockerfile +sudo docker build -t keystone:mitaka . +``` + +### Start RabbitMQ + +```bash +sudo docker network create -d bridge --subnet=172.18.0.0/16 --gateway=172.18.0.1 moon +sudo docker run -dti --net=moon --hostname messenger --name messenger --link messenger:messenger -e RABBITMQ_DEFAULT_USER=moon -e RABBITMQ_DEFAULT_PASS=p4sswOrd1 -e RABBITMQ_NODENAME=rabbit@messenger -e RABBITMQ_DEFAULT_VHOST=moon -p 5671:5671 -p 5672:5672 rabbitmq:3-management +``` + +### Start MySQL server + +```bash +sudo docker run -dti --net=moon --hostname db --name db -e MYSQL_ROOT_PASSWORD=p4sswOrd1 -e MYSQL_DATABASE=moon -e MYSQL_USER=moon -e MYSQL_PASSWORD=p4sswOrd1 -p 3306:3306 mysql:latest +``` + +### Start an OpenStack environment + +```bash +sudo docker run -dti --net moon --name keystone --hostname=keystone -e DB_HOST=db -e DB_PASSWORD_ROOT=p4sswOrd1 -p 35357:35357 -p 5000:5000 keystone:mitaka +``` + +### Build python packages for all components + +```bash +cd ${MOON_HOME}/moon_orchestrator +sudo pip3 install pip --upgrade +cd ${MOON_HOME}/bin +source build_all.sh +``` + +### Start Orchestrator + +To start the Moon platform, you have to run the Orchestrator. + +```bash +cd ${MOON_HOME}/moon_orchestrator +sudo apt-get install python3-venv (or apt-get install -y python3 python-virtualenv on Ubuntu 14.04) +pyvenv tests/venv (or virtualenv tests/venv on Ubuntu 14.04) +. tests/venv/bin/activate +sudo pip3 install -r requirements.txt --upgrade +sudo pip3 install dist/moon_db-0.1.0.tar.gz --upgrade +sudo pip3 install dist/moon_utilities-0.1.0.tar.gz --upgrade +sudo pip3 install . --upgrade +# Check the proxy settings and edit dist_dir variable in $(MOON_HOME)/moon_orchestrator/etc/moon.conf +# Adapt the path used in the cd command in $(MOON_HOME)/bin/start.sh +source ../bin/start.sh +``` + +### Tests +```bash +sudo pip3 install pytest +cd ${MOON_HOME}/moon_interface/tests/apitests +pytest +``` + + +### Relaunch Keystone docker +If error of `get_keystone_projects()`, then relaunch the Keystone docker, and wait 40 seconds!!! +```bash +docker rm -f keystone +docker run -dti --net moon --name keystone --hostname=keystone -e DB_HOST=db -e DB_PASSWORD_ROOT=p4sswOrd1 -p 35357:35357 -p 5000:5000 keystone:mitaka +``` + +### Add default data in DB +Pre-fill the DB with a RBAC policy +```bash +cd ${MOON_HOME}/moon_interface/tests/apitests +python3 populate_default_values.py scenario/ rbac.py +``` + + +### Get some logs + +```bash +docker ps +docker logs messenger +docker logs keystone +docker logs moon_router +docker logs moon_interface +``` + +### Get some statistics + +```bash +docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}" +``` + +### Get the API in PDF + +```bash +cd ${MOON_HOME}/moon_interface/tools +sudo pip3 install requests +sudo apt-get install pandoc +/usr/bin/python3 api2rst.py +sudo apt-get install texlive-latex-extra +pandoc api.rst -o api.pdf +evince api.pdf +``` + +## How to hack the Moon platform + +### Force the build of components + +If you want to rebuild one or more component, you have to modify the configuration file `moon.conf`. + +For example, if you want to rebuild the moon_interface, got to the `[interface]` section and delete the +value of the container key like this: + +``` +[interface] +host=172.18.0.11 +port=38001 +# Name of the container to download (if empty build from scratch) +# example: container=moon/moon_interface:latest +container= +``` + +You can configure the interface, the router and both the security_function and security_policy. +You can also force the version of the component like this: `container=moon/moon_interface:4.0.0` + +### Update the moon_interface + +Go to the directory `${MOON_HOME}/moon_interface` and update the code accordingly to your needs, +then update the python package. + +```bash +cd ${MOON_HOME}/moon_interface +python setup.py sdist +cp dist/moon_interface_* ../moon_orchestrator/dist +# kill moon_orchestrator if needed and restart it +``` + +### Update the moon_secrouter + +Go to the directory `${MOON_HOME}/moon_secrouter` and update the code accordingly to your needs, +then update the python package. + +```bash +cd ${MOON_HOME}/moon_secrouter +python setup.py sdist +cp dist/moon_secrouter* ../moon_orchestrator/dist +# kill moon_orchestrator if needed and restart it +``` + +## Problems that may arise + +If the moon_orchestrator doesn't want to start +(with, for example, the following error: `docker.errors.APIError: 409 Client Error: Conflict`), +check if the router and interface containers still exist and kill and delete them: + +```bash +docker kill moon_interface +docker kill moon_router +docker rm moon_interface +docker rm moon_router +``` + +If the moon_orchestrator complains that it cannot request the RabbitMQ server, +check if the messenger server is up and running: + +```bash +docker ps +# you must see the messenger running here +# if not, restart it +docker run -dti --net=moon --hostname messenger --name messenger --link messenger:messenger -e RABBITMQ_DEFAULT_USER=moon -e RABBITMQ_DEFAULT_PASS=password -e RABBITMQ_NODENAME=rabbit@messenger -e RABBITMQ_DEFAULT_VHOST=moon -p 5671:5671 -p 5672:5672 rabbitmq:3-management +``` diff --git a/moonv4/TODO b/moonv4/TODO new file mode 100644 index 00000000..2d341a84 --- /dev/null +++ b/moonv4/TODO @@ -0,0 +1,32 @@ +Here is a list of what must be done to have complete version of the Moon platform. + +Actions that must be done before the next version: + +- manage a token/uuid (ie session ID) in the moon_interface component +- update RabbitMQ connections in security_function to have work queues instead of RPC +- add a timestamps in moon_router to know if the database has been modified +- rename moon_db and moon_utilities because they are not container but just libraries +- work on moonclient because it doesn't work with the new data model +- check all input from moon_interface (check that input data are correct and safe) +- Move @enforce from moon_db to API in Moon_Manager +- Need to work on unit tests with the new data model + +Bugs to fix: + +- Connect the authz functionality with the enforce decorator +- The intra_extension ID parameter must be given when the container is ran and not when it is build + (security_function) +- The configuration (moon.conf) must be retrieved when the container is ran and not when it is build +- When a container is deleted, the reference is not deleted from CONTAINERS in orchestrator +- All request to moon_interface generally end with a 200 HTTP code even if there is an error + +Other actions: + +- Some cleaning in all classes +- Write Installation procedures +- Write User and administrator documentation +- Run unit tests +- Add and run integration tests +- Add a logging system +- moon_orchestrator in a docker +- Add security on RabbitMQ transactions (auth+crypt) diff --git a/moonv4/moon_authz/LICENSE b/moonv4/moon_authz/LICENSE new file mode 100644 index 00000000..4143aac2 --- /dev/null +++ b/moonv4/moon_authz/LICENSE @@ -0,0 +1,204 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +--- License for python-keystoneclient versions prior to 2.1 --- + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of this project nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/moonv4/moon_authz/MANIFEST.in b/moonv4/moon_authz/MANIFEST.in new file mode 100644 index 00000000..1f674d50 --- /dev/null +++ b/moonv4/moon_authz/MANIFEST.in @@ -0,0 +1,9 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +include README.rst +include LICENSE +include setup.py +include requirements.txt diff --git a/moonv4/moon_authz/README.rst b/moonv4/moon_authz/README.rst new file mode 100644 index 00000000..ded4e99a --- /dev/null +++ b/moonv4/moon_authz/README.rst @@ -0,0 +1,9 @@ +Core module for the Moon project +================================ + +This package contains the core module for the Moon project +It is designed to provide authorization features to all OpenStack components. + +For any other information, refer to the parent project: + + https://git.opnfv.org/moon diff --git a/moonv4/moon_authz/moon_authz/__init__.py b/moonv4/moon_authz/moon_authz/__init__.py new file mode 100644 index 00000000..903c6518 --- /dev/null +++ b/moonv4/moon_authz/moon_authz/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +__version__ = "0.1.0" diff --git a/moonv4/moon_authz/moon_authz/__main__.py b/moonv4/moon_authz/moon_authz/__main__.py new file mode 100644 index 00000000..be483962 --- /dev/null +++ b/moonv4/moon_authz/moon_authz/__main__.py @@ -0,0 +1,3 @@ +from moon_authz.server import main + +main() diff --git a/moonv4/moon_authz/moon_authz/api/__init__.py b/moonv4/moon_authz/moon_authz/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/moonv4/moon_authz/moon_authz/api/authorization.py b/moonv4/moon_authz/moon_authz/api/authorization.py new file mode 100644 index 00000000..248a9565 --- /dev/null +++ b/moonv4/moon_authz/moon_authz/api/authorization.py @@ -0,0 +1,445 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import copy +import itertools +from oslo_log import log as logging +from oslo_config import cfg +from moon_utilities.security_functions import call, Context +from moon_utilities.misc import get_uuid_from_name +from moon_utilities import exceptions +from moon_db.core import PDPManager +from moon_db.core import ModelManager +from moon_db.core import PolicyManager + +# TODO (asteroide): +# - end the dev of the context +# - rebuild the authorization function according to the context +# - call the next security function +# - call the master if an element is absent + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class PDP: + + def __init__(self, context): + self.__context = context + + +class Authorization(object): + """ + Retrieve the current status of all components. + """ + + __version__ = "0.1.0" + pdp_id = None + meta_rule_id = None + keystone_project_id = None + + def __init__(self, component_id): + self.component_id = component_id + LOG.info("ext={}".format(component_id)) + for _id_value in component_id.split("_"): + LOG.info("_id_value={}".format(_id_value.split(":"))) + _type, _id = _id_value.split(":") + if _type == "pdp": + self.pdp_id = _id + elif _type == "metarule": + self.meta_rule_id = _id + elif _type == "project": + self.keystone_project_id = _id + # self.manager = IntraExtensionAdminManager + # self.context = {"id": self.component_id, "user_id": "admin"} + # self.aggregation_algorithm_dict = ConfigurationManager.driver.get_aggregation_algorithms_dict() + # self.__subjects = None + # self.__objects = None + # self.__actions = None + # self.__subject_scopes = None + # self.__object_scopes = None + # self.__action_scopes = None + # self.__subject_categories = None + # self.__object_categories = None + # self.__action_categories = None + # self.__subject_assignments = None + # self.__object_assignments = None + # self.__action_assignments = None + # self.__sub_meta_rules = None + # self.__rules = None + # self.aggregation_algorithm_id = None + + # @property + # def subjects(self): + # if not self.__subjects: + # self.__subjects = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_subjects", args={}) + # if "subjects" in self.__subjects: + # return self.__subjects + # else: + # LOG.error("An error occurred {}".format(self.__subjects)) + # return self.__subjects + # + # @property + # def objects(self): + # if not self.__objects: + # self.__objects = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_objects", args={}) + # if "objects" in self.__objects: + # return self.__objects + # else: + # LOG.error("An error occurred {}".format(self.__objects)) + # return self.__objects + # + # @property + # def actions(self): + # if not self.__actions: + # self.__actions = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_actions", args={}) + # if "actions" in self.__actions: + # return self.__actions + # else: + # LOG.error("An error occurred {}".format(self.__actions)) + # return self.__actions + # + # @property + # def subject_scopes(self): + # if not self.__subject_scopes: + # self.__subject_scopes = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_subject_scopes", args={}) + # if "subject_scopes" in self.__subject_scopes: + # return self.__subject_scopes + # else: + # LOG.error("An error occurred {}".format(self.__subject_scopes)) + # return self.__subject_scopes + # + # @property + # def object_scopes(self): + # if not self.__object_scopes: + # self.__object_scopes = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_object_scopes", args={}) + # if "object_scopes" in self.__object_scopes: + # return self.__object_scopes + # else: + # LOG.error("An error occurred {}".format(self.__object_scopes)) + # return self.__object_scopes + # + # @property + # def action_scopes(self): + # if not self.__action_scopes: + # self.__action_scopes = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_action_scopes", args={}) + # if "action_scopes" in self.__action_scopes: + # return self.__action_scopes + # else: + # LOG.error("An error occurred {}".format(self.__action_scopes)) + # return self.__action_scopes + # + # @property + # def subject_categories(self): + # if not self.__subject_categories: + # self.__subject_categories = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_subject_categories", args={}) + # if "subject_categories" in self.__subject_categories: + # return self.__subject_categories + # else: + # LOG.error("An error occurred {}".format(self.__subject_categories)) + # return self.__subject_categories + # + # @property + # def object_categories(self): + # if not self.__object_categories: + # self.__object_categories = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_object_categories", args={}) + # if "object_categories" in self.__object_categories: + # return self.__object_categories + # else: + # LOG.error("An error occurred {}".format(self.__object_categories)) + # return self.__object_categories + # + # @property + # def action_categories(self): + # if not self.__action_categories: + # self.__action_categories = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_action_categories", args={}) + # if "action_categories" in self.__action_categories: + # return self.__action_categories + # else: + # LOG.error("An error occurred {}".format(self.__action_categories)) + # return self.__action_categories + # + # @property + # def subject_assignments(self): + # if not self.__subject_assignments: + # context = copy.deepcopy(self.context) + # context['sid'] = None + # context['scid'] = None + # args = {'ssid': None} + # self.__subject_assignments = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=context, + # method="get_subject_assignments", args=args) + # if "subject_assignments" in self.__subject_assignments: + # return self.__subject_assignments + # else: + # LOG.error("An error occurred {}".format(self.__subject_assignments)) + # return self.__subject_assignments + # + # @property + # def object_assignments(self): + # if not self.__object_assignments: + # context = copy.deepcopy(self.context) + # context['sid'] = None + # context['scid'] = None + # args = {'ssid': None} + # self.__object_assignments = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=context, + # method="get_object_assignments", args=args) + # if "object_assignments" in self.__object_assignments: + # return self.__object_assignments + # else: + # LOG.error("An error occurred {}".format(self.__object_assignments)) + # return self.__object_assignments + # + # @property + # def action_assignments(self): + # if not self.__action_assignments: + # context = copy.deepcopy(self.context) + # context['sid'] = None + # context['scid'] = None + # args = {'ssid': None} + # self.__action_assignments = call("moon_secpolicy_{}".format(self.intra_extension_id), ctx=context, + # method="get_action_assignments", args=args) + # if "action_assignments" in self.__action_assignments: + # return self.__action_assignments + # else: + # LOG.error("An error occurred {}".format(self.__action_assignments)) + # return self.__action_assignments + # + # @property + # def sub_meta_rules(self): + # if not self.__sub_meta_rules: + # self.__sub_meta_rules = call("moon_secfunction_{}".format(self.intra_extension_id), ctx=self.context, + # method="get_sub_meta_rules", args={}) + # if "sub_meta_rules" in self.__sub_meta_rules: + # return self.__sub_meta_rules + # else: + # LOG.error("An error occurred {}".format(self.__sub_meta_rules)) + # return self.__sub_meta_rules + # + # @property + # def rules(self): + # if not self.__rules: + # self.__rules = dict() + # for _id, _value in self.sub_meta_rules["sub_meta_rules"].items(): + # context = copy.deepcopy(self.context) + # context["sub_meta_rule_id"] = _id + # __elements = call("moon_secfunction_{}".format(self.intra_extension_id), ctx=context, + # method="get_rules", args={}) + # if "rules" in __elements: + # self.__rules[_id] = __elements + # else: + # LOG.error("An error occurred {}".format(__elements)) + # return self.__rules + + # def __get_authz_buffer(self, subject_id, object_id, action_id): + # """ + # :param intra_extension_id: + # :param subject_id: + # :param object_id: + # :param action_id: + # :return: authz_buffer = { + # 'subject_id': xxx, + # 'object_id': yyy, + # 'action_id': zzz, + # 'subject_assignments': { + # 'subject_category1': [], + # 'subject_category2': [], + # ... + # }, + # 'object_assignments': {}, + # 'action_assignments': {}, + # } + # """ + # authz_buffer = dict() + # # Sometimes it is not the subject ID but the User Keystone ID, so, we have to check + # subjects_dict = copy.deepcopy(self.subjects) + # if subject_id not in subjects_dict["subjects"].keys(): + # for _subject_id in subjects_dict["subjects"]: + # if subjects_dict["subjects"][_subject_id]['keystone_id']: + # subject_id = _subject_id + # break + # authz_buffer['subject_id'] = subject_id + # authz_buffer['object_id'] = object_id + # authz_buffer['action_id'] = action_id + # meta_data_dict = dict() + # meta_data_dict["subject_categories"] = copy.deepcopy(self.subject_categories["subject_categories"]) + # meta_data_dict["object_categories"] = copy.deepcopy(self.object_categories["object_categories"]) + # meta_data_dict["action_categories"] = copy.deepcopy(self.action_categories["action_categories"]) + # subject_assignment_dict = copy.deepcopy(self.subject_assignments['subject_assignments'][subject_id]) + # LOG.info("__get_authz_buffer self.object_assignments['object_assignments']={}".format(self.object_assignments['object_assignments'])) + # LOG.info("__get_authz_buffer object_id={}".format(object_id)) + # object_assignment_dict = copy.deepcopy(self.object_assignments['object_assignments'][object_id]) + # action_assignment_dict = copy.deepcopy(self.action_assignments['action_assignments'][action_id]) + # + # authz_buffer['subject_assignments'] = dict() + # authz_buffer['object_assignments'] = dict() + # authz_buffer['action_assignments'] = dict() + # + # for _subject_category in meta_data_dict['subject_categories']: + # authz_buffer['subject_assignments'][_subject_category] = list(subject_assignment_dict[_subject_category]) + # for _object_category in meta_data_dict['object_categories']: + # authz_buffer['object_assignments'][_object_category] = list(object_assignment_dict[_object_category]) + # for _action_category in meta_data_dict['action_categories']: + # authz_buffer['action_assignments'][_action_category] = list(action_assignment_dict[_action_category]) + # return authz_buffer + # + # def __get_decision_dict(self, subject_id, object_id, action_id): + # """Check authorization for a particular action. + # + # :param intra_extension_id: UUID of an IntraExtension + # :param subject_id: subject UUID of the request + # :param object_id: object UUID of the request + # :param action_id: action UUID of the request + # :return: True or False or raise an exception + # :raises: + # """ + # authz_buffer = self.__get_authz_buffer(subject_id, object_id, action_id) + # decision_buffer = dict() + # + # meta_rule_dict = copy.deepcopy(self.sub_meta_rules['sub_meta_rules']) + # rules_dict = copy.deepcopy(self.rules) + # for sub_meta_rule_id in meta_rule_dict: + # if meta_rule_dict[sub_meta_rule_id]['algorithm'] == 'inclusion': + # decision_buffer[sub_meta_rule_id] = algorithms.inclusion( + # authz_buffer, + # meta_rule_dict[sub_meta_rule_id], + # rules_dict[sub_meta_rule_id]['rules'].values()) + # elif meta_rule_dict[sub_meta_rule_id]['algorithm'] == 'comparison': + # decision_buffer[sub_meta_rule_id] = algorithms.comparison( + # authz_buffer, + # meta_rule_dict[sub_meta_rule_id], + # rules_dict[sub_meta_rule_id]['rules'].values()) + # + # return decision_buffer + # + # def __authz(self, subject_id, object_id, action_id): + # decision = False + # decision_dict = dict() + # try: + # decision_dict = self.__get_decision_dict(subject_id, object_id, action_id) + # except (exceptions.SubjectUnknown, exceptions.ObjectUnknown, exceptions.ActionUnknown) as e: + # # maybe we need to synchronize with the master + # pass + # # if CONF.slave.slave_name and CONF.slave.master_url: + # # self.get_data_from_master() + # # decision_dict = self.__get_decision_dict(subject_id, object_id, action_id) + # + # try: + # # aggregation_algorithm_id = IntraExtensionAdminManager.get_aggregation_algorithm_id( + # # "admin", + # # self.intra_extension_id)['aggregation_algorithm'] + # if not self.aggregation_algorithm_id: + # self.aggregation_algorithm_id = self.intra_extension['aggregation_algorithm'] + # except Exception as e: + # LOG.error(e, exc_info=True) + # LOG.error(self.intra_extension) + # return { + # 'authz': False, + # 'comment': "Aggregation algorithm not set" + # } + # if self.aggregation_algorithm_dict[self.aggregation_algorithm_id]['name'] == 'all_true': + # decision = algorithms.all_true(decision_dict) + # elif self.aggregation_algorithm_dict[self.aggregation_algorithm_id]['name'] == 'one_true': + # decision = algorithms.one_true(decision_dict) + # if not decision_dict or not decision: + # raise exceptions.AuthzException("{} {}-{}-{}".format(self.intra_extension['id'], subject_id, action_id, object_id)) + # return { + # 'authz': decision, + # 'comment': "{} {}-{}-{}".format(self.intra_extension['id'], subject_id, action_id, object_id) + # } + # + # def authz_bak(self, ctx, args): + # """Return the authorization for a specific request + # + # :param ctx: { + # "subject_name" : "string name", + # "action_name" : "string name", + # "object_name" : "string name" + # } + # :param args: {} + # :return: { + # "authz": "True or False", + # "message": "optional message" + # } + # """ + # intra_extension_id = ctx["id"] + # try: + # subject_id = get_uuid_from_name(ctx["subject_name"], self.subjects['subjects']) + # object_id = get_uuid_from_name(ctx["object_name"], self.objects['objects']) + # action_id = get_uuid_from_name(ctx["action_name"], self.actions['actions']) + # authz_result = self.__authz(subject_id, object_id, action_id) + # return authz_result + # except Exception as e: + # LOG.error(e, exc_info=True) + # return {"authz": False, + # "error": str(e), + # "intra_extension_id": intra_extension_id, + # "ctx": ctx, "args": args} + # + # return {"authz": False} + + def __check_rules(self, context): + scopes_list = list() + current_header_id = context.headers[context.index]['id'] + current_pdp = context.pdp_set[current_header_id] + category_list = list() + category_list.extend(current_pdp["meta_rules"]["subject_categories"]) + category_list.extend(current_pdp["meta_rules"]["action_categories"]) + category_list.extend(current_pdp["meta_rules"]["object_categories"]) + for category in category_list: + if not current_pdp['target'][category]: + LOG.warning("Empty assignment detected: {} target={}".format(category, current_pdp['target'])) + return False, "Empty assignment detected..." + scopes_list.append(current_pdp['target'][category]) + scopes_list.append([True, ]) + rules = PolicyManager.get_rules_dict(user_id="admin", + policy_id=self.policy_id, + meta_rule_id=current_header_id).values() + for item in itertools.product(*scopes_list): + if list(item) in rules: + return True, "" + LOG.warning("No rule match the request...") + return False, "No rule match the request..." + + def authz(self, ctx, args): + LOG.info("authz {}".format(ctx)) + keystone_project_id = ctx["id"] + try: + if "authz_context" not in ctx: + ctx["authz_context"] = Context(keystone_project_id, + ctx["subject_name"], + ctx["object_name"], + ctx["action_name"], + ctx["request_id"]).to_dict() + LOG.info("Context={}".format(ctx["authz_context"])) + else: + ctx["authz_context"].index += 1 + result, message = self.__check_rules(ctx["authz_context"]) + # if ctx["authz_context"].index < len(ctx["authz_context"].headers): + del ctx["authz_context"] + return {"authz": result, + "error": message, + "pdp_id": self.pdp_id, + "ctx": ctx, "args": args} + except Exception as e: + try: + LOG.error(ctx["authz_context"]) + # del ctx["authz_context"] + except KeyError: + LOG.error("Cannot find \"authz_context\" in context") + LOG.error(e, exc_info=True) + return {"authz": False, + "error": str(e), + "pdp_id": self.pdp_id, + "ctx": ctx, "args": args} + diff --git a/moonv4/moon_authz/moon_authz/api/generic.py b/moonv4/moon_authz/moon_authz/api/generic.py new file mode 100644 index 00000000..db61188b --- /dev/null +++ b/moonv4/moon_authz/moon_authz/api/generic.py @@ -0,0 +1,28 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +class Status(object): + """ + Retrieve the current status of all components. + """ + + __version__ = "0.1.0" + + def get_status(self, ctx, args): + return {"status": "Running"} + + +class Logs(object): + """ + Retrieve the current status of all components. + """ + + __version__ = "0.1.0" + + def get_logs(self, ctx, args): + return {"error": "NotImplemented"} + + diff --git a/moonv4/moon_authz/moon_authz/messenger.py b/moonv4/moon_authz/moon_authz/messenger.py new file mode 100644 index 00000000..8ebd1633 --- /dev/null +++ b/moonv4/moon_authz/moon_authz/messenger.py @@ -0,0 +1,63 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from oslo_config import cfg +import oslo_messaging +import hashlib +import time +from oslo_log import log as logging +from moon_authz.api.generic import Status, Logs +from moon_authz.api.authorization import Authorization +from moon_utilities.security_functions import call +from moon_utilities.api import APIList + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class Server: + + def __init__(self, component_id, keystone_project_id): + self.TOPIC = "authz_"+hashlib.sha224(component_id.encode("utf-8")).hexdigest() + self.transport = oslo_messaging.get_transport(cfg.CONF) + self.target = oslo_messaging.Target(topic=self.TOPIC, server='moon_authz_server1') + # ctx = {'user_id': 'admin', 'id': component_id, 'method': 'get_intra_extensions'} + # if CONF.slave.slave_name: + # ctx['call_master'] = True + # intra_extension = call( + # endpoint="security_router", + # ctx=ctx, + # method='route', + # args={} + # ) + # if "intra_extensions" not in intra_extension: + # LOG.error("Error reading intra_extension from router") + # LOG.error("intra_extension: {}".format(intra_extension)) + # raise IntraExtensionUnknown + # component_id = list(intra_extension["intra_extensions"].keys())[0] + LOG.info("Starting MQ server with topic: {}".format(self.TOPIC)) + self.endpoints = [ + APIList((Status, Logs)), + Status(), + Logs(), + Authorization(component_id) + ] + self.server = oslo_messaging.get_rpc_server(self.transport, self.target, self.endpoints, + executor='threading', + access_policy=oslo_messaging.DefaultRPCAccessPolicy) + + def run(self): + try: + self.server.start() + while True: + time.sleep(1) + except KeyboardInterrupt: + print("Stopping server by crtl+c") + except SystemExit: + print("Stopping server") + + self.server.stop() + self.server.wait() + diff --git a/moonv4/moon_authz/moon_authz/server.py b/moonv4/moon_authz/moon_authz/server.py new file mode 100644 index 00000000..0c2a36ff --- /dev/null +++ b/moonv4/moon_authz/moon_authz/server.py @@ -0,0 +1,36 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import os +from oslo_config import cfg +from oslo_log import log as logging +# cfg.CONF.register_cli_opt(cfg.StrOpt('function_type', positional=True, +# help="The type of function managed by this component (example 'authz').")) +cfg.CONF.register_cli_opt(cfg.StrOpt('uuid', positional=True, + help="The ID of the component managed here.")) +cfg.CONF.register_cli_opt(cfg.StrOpt('keystone_project_id', positional=True, + help="The ID of the component managed here.")) +from moon_utilities import options # noqa +from moon_authz.messenger import Server + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF +DOMAIN = "moon_authz" + +__CWD__ = os.path.dirname(os.path.abspath(__file__)) + + +def main(): + component_id = CONF.uuid + keystone_project_id = CONF.keystone_project_id + # function_type = CONF.intra_extension_id.replace(component_id, "").strip('_') + LOG.info("Starting server with IP {} on component {}".format( + CONF.security_router.host, component_id)) + server = Server(component_id=component_id, keystone_project_id=keystone_project_id) + server.run() + + +if __name__ == '__main__': + main() diff --git a/moonv4/moon_authz/requirements.txt b/moonv4/moon_authz/requirements.txt new file mode 100644 index 00000000..8faf9439 --- /dev/null +++ b/moonv4/moon_authz/requirements.txt @@ -0,0 +1 @@ +kombu !=4.0.1,!=4.0.0 \ No newline at end of file diff --git a/moonv4/moon_authz/setup.py b/moonv4/moon_authz/setup.py new file mode 100644 index 00000000..a8dcd0c4 --- /dev/null +++ b/moonv4/moon_authz/setup.py @@ -0,0 +1,47 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from setuptools import setup, find_packages +import moon_authz + + +setup( + + name='moon_authz', + + version=moon_authz.__version__, + + packages=find_packages(), + + author="Thomas Duval", + + author_email="thomas.duval@orange.com", + + description="", + + long_description=open('README.rst').read(), + + # install_requires= , + + include_package_data=True, + + url='https://git.opnfv.org/moon', + + classifiers=[ + "Programming Language :: Python", + "Development Status :: 1 - Planning", + "License :: OSI Approved", + "Natural Language :: French", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + ], + + entry_points={ + 'console_scripts': [ + 'moon_authz = moon_authz.server:main', + ], + } + +) diff --git a/moonv4/moon_db/Changelog b/moonv4/moon_db/Changelog new file mode 100644 index 00000000..47e3c5f7 --- /dev/null +++ b/moonv4/moon_db/Changelog @@ -0,0 +1,12 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +CHANGES +======= + +0.1.0 +----- +- First version of the moon_db library. diff --git a/moonv4/moon_db/LICENSE b/moonv4/moon_db/LICENSE new file mode 100644 index 00000000..4143aac2 --- /dev/null +++ b/moonv4/moon_db/LICENSE @@ -0,0 +1,204 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +--- License for python-keystoneclient versions prior to 2.1 --- + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of this project nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/moonv4/moon_db/MANIFEST.in b/moonv4/moon_db/MANIFEST.in new file mode 100644 index 00000000..24ccc449 --- /dev/null +++ b/moonv4/moon_db/MANIFEST.in @@ -0,0 +1,11 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +include README.rst +include LICENSE +include setup.py +include requirements.txt +graft tests +graft bin \ No newline at end of file diff --git a/moonv4/moon_db/README.rst b/moonv4/moon_db/README.rst new file mode 100644 index 00000000..afee9be5 --- /dev/null +++ b/moonv4/moon_db/README.rst @@ -0,0 +1,9 @@ +DB module for the Moon project +============================== + +This package contains the database module for the Moon project +It is designed to provide a driver to access the Moon database. + +For any other information, refer to the parent project: + + https://git.opnfv.org/moon diff --git a/moonv4/moon_db/Vagrantfile b/moonv4/moon_db/Vagrantfile new file mode 100644 index 00000000..488d8aef --- /dev/null +++ b/moonv4/moon_db/Vagrantfile @@ -0,0 +1,71 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure("2") do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + # Every Vagrant development environment requires a box. You can search for + # boxes at https://atlas.hashicorp.com/search. + config.vm.box = "gbarbieru/xenial" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider "virtualbox" do |vb| + # # Display the VirtualBox GUI when booting the machine + # vb.gui = true + # + # # Customize the amount of memory on the VM: + # vb.memory = "1024" + # end + # + # View the documentation for the provider you are using for more + # information on available options. + + # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies + # such as FTP and Heroku are also available. See the documentation at + # https://docs.vagrantup.com/v2/push/atlas.html for more information. + # config.push.define "atlas" do |push| + # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME" + # end + + # Enable provisioning with a shell script. Additional provisioners such as + # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the + # documentation for more information about their specific syntax and use. + # config.vm.provision "shell", inline: <<-SHELL + # apt-get update + # apt-get install -y apache2 + # SHELL +end diff --git a/moonv4/moon_db/bin/drop_tables.sql b/moonv4/moon_db/bin/drop_tables.sql new file mode 100644 index 00000000..f5f65ea7 --- /dev/null +++ b/moonv4/moon_db/bin/drop_tables.sql @@ -0,0 +1,18 @@ +use moon; +drop table action_assignments; +drop table object_assignments; +drop table subject_assignments; +drop table subject_scopes; +drop table action_scopes; +drop table object_scopes; +drop table action_categories; +drop table subject_categories; +drop table object_categories; +drop table rules; +drop table sub_meta_rules; +drop table actions; +drop table objects; +drop table subjects; +drop table tenants; +drop table intra_extensions; +show tables; diff --git a/moonv4/moon_db/moon_db/__init__.py b/moonv4/moon_db/moon_db/__init__.py new file mode 100644 index 00000000..64e88e23 --- /dev/null +++ b/moonv4/moon_db/moon_db/__init__.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +# try: +# from moon_utilities import options # noqa +# except ImportError: +# # mandatory when we just want to execute the setup.py +# options = None + +# try: +# from moon_db.core import IntraExtensionRootManager, IntraExtensionAdminManager, IntraExtensionAuthzManager # noqa +# except ImportError: +# # mandatory when we just want to execute the setup.py +# IntraExtensionRootManager, IntraExtensionAdminManager, IntraExtensionAuthzManager = None, None, None + +# from moon_utilities import options # noqa +# from moon_db.core import IntraExtensionRootManager, IntraExtensionAdminManager, IntraExtensionAuthzManager # noqa + +__version__ = "0.1.0" + diff --git a/moonv4/moon_db/moon_db/api/__init__.py b/moonv4/moon_db/moon_db/api/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/moonv4/moon_db/moon_db/api/keystone.py b/moonv4/moon_db/moon_db/api/keystone.py new file mode 100644 index 00000000..b5d7e3a6 --- /dev/null +++ b/moonv4/moon_db/moon_db/api/keystone.py @@ -0,0 +1,106 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import os +import requests +import json +from uuid import uuid4 +from oslo_log import log as logging +from oslo_config import cfg +from moon_utilities import exceptions +from moon_db.api.managers import Managers +from moon_utilities.security_functions import filter_input, login, logout + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class KeystoneManager(Managers): + + def __init__(self, connector=None): + self.driver = connector.driver + Managers.KeystoneManager = self + self.__url = CONF.keystone.url + self.__user = CONF.keystone.user + self.__password = CONF.keystone.password + self.__domain = CONF.keystone.domain + self.__project = CONF.keystone.project + try: + os.environ.pop("http_proxy") + os.environ.pop("https_proxy") + except KeyError: + pass + + def __get(self, endpoint, _exception=exceptions.KeystoneError): + _headers = login() + req = requests.get("{}{}".format(self.__url, endpoint), headers=_headers, verify=False) + if req.status_code not in (200, 201): + LOG.error(req.text) + raise _exception + data = req.json() + logout(_headers) + return data + + def __post(self, endpoint, data=None, _exception=exceptions.KeystoneError): + _headers = login() + req = requests.post("{}{}".format(self.__url, endpoint), + data=json.dumps(data), + headers=_headers, verify=False) + if req.status_code == 409: + LOG.warning(req.text) + raise exceptions.KeystoneUserConflict + if req.status_code not in (200, 201): + LOG.error(req.text) + raise _exception + data = req.json() + logout(_headers) + return data + + def list_projects(self): + return self.__get(endpoint="/projects/", _exception=exceptions.KeystoneProjectError) + + @filter_input + def create_project(self, tenant_dict): + if "name" not in tenant_dict: + raise exceptions.KeystoneProjectError("Cannot get the project name.") + _project = { + "project": { + "description": tenant_dict['description'] if 'description' in tenant_dict else "", + "domain_id": tenant_dict['domain'] if 'domain' in tenant_dict else "default", + "enabled": True, + "is_domain": False, + "name": tenant_dict['name'] + } + } + return self.__post(endpoint="/projects/", + data=_project, + _exception=exceptions.KeystoneProjectError) + + @filter_input + def get_user_by_name(self, username, domain_id="default"): + return self.__get(endpoint="/users?name={}&domain_id={}".format(username, domain_id), + _exception=exceptions.KeystoneUserError) + + @filter_input + def create_user(self, subject_dict): + _user = { + "user": { + "enabled": True, + "name": subject_dict['name'] if 'name' in subject_dict else uuid4().hex, + } + } + if 'project' in subject_dict: + _user['user']['default_project_id'] = subject_dict['project'] + if 'domain' in subject_dict: + _user['user']['domain_id'] = subject_dict['domain'] + if 'password' in subject_dict: + _user['user']['password'] = subject_dict['password'] + try: + return self.__post(endpoint="/users/", + data=_user, + _exception=exceptions.KeystoneUserError) + except exceptions.KeystoneUserConflict: + return True + diff --git a/moonv4/moon_db/moon_db/api/managers.py b/moonv4/moon_db/moon_db/api/managers.py new file mode 100644 index 00000000..48ac9ce1 --- /dev/null +++ b/moonv4/moon_db/moon_db/api/managers.py @@ -0,0 +1,15 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from oslo_log import log as logging +LOG = logging.getLogger(__name__) + + +class Managers(object): + """Object that links managers together""" + ModelManager = None + KeystoneManager = None + PDPManager = None + PolicyManager = None diff --git a/moonv4/moon_db/moon_db/api/model.py b/moonv4/moon_db/moon_db/api/model.py new file mode 100644 index 00000000..c1620da3 --- /dev/null +++ b/moonv4/moon_db/moon_db/api/model.py @@ -0,0 +1,141 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import os +import re +import types +import json +import copy +from uuid import uuid4 +from oslo_config import cfg +from oslo_log import log as logging +import requests +from moon_utilities import exceptions +from moon_utilities.security_functions import filter_input, enforce +# from moon_db.api import algorithms +from moon_db.api.managers import Managers + + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class ModelManager(Managers): + + def __init__(self, connector=None): + self.driver = connector.driver + Managers.ModelManager = self + + @enforce(("read", "write"), "models") + def update_model(self, user_id, model_id, value): + if model_id not in self.driver.get_models(model_id=model_id): + raise exceptions.ModelUnknown + return self.driver.update_model(model_id=model_id, value=value) + + @enforce(("read", "write"), "models") + def delete_model(self, user_id, model_id): + if model_id not in self.driver.get_models(model_id=model_id): + raise exceptions.ModelUnknown + # TODO (asteroide): check that no policy is connected to this model + return self.driver.delete_model(model_id=model_id) + + @enforce(("read", "write"), "models") + def add_model(self, user_id, model_id=None, value=None): + if model_id in self.driver.get_models(model_id=model_id): + raise exceptions.ModelExisting + if not model_id: + model_id = uuid4().hex + return self.driver.add_model(model_id=model_id, value=value) + + @enforce("read", "models") + def get_models(self, user_id, model_id=None): + return self.driver.get_models(model_id=model_id) + + @enforce(("read", "write"), "meta_rules") + def set_meta_rule(self, user_id, meta_rule_id, value): + if meta_rule_id not in self.driver.get_meta_rules(meta_rule_id=meta_rule_id): + raise exceptions.MetaRuleUnknown + return self.driver.set_meta_rule(meta_rule_id=meta_rule_id, value=value) + + @enforce("read", "meta_rules") + def get_meta_rules(self, user_id, meta_rule_id=None): + return self.driver.get_meta_rules(meta_rule_id=meta_rule_id) + + @enforce(("read", "write"), "meta_rules") + def add_meta_rule(self, user_id, meta_rule_id=None, value=None): + if meta_rule_id in self.driver.get_meta_rules(meta_rule_id=meta_rule_id): + raise exceptions.MetaRuleExisting + if not meta_rule_id: + meta_rule_id = uuid4().hex + LOG.info("add_meta_rule {}".format(value)) + return self.driver.set_meta_rule(meta_rule_id=meta_rule_id, value=value) + + @enforce(("read", "write"), "meta_rules") + def delete_meta_rule(self, user_id, meta_rule_id=None): + if meta_rule_id not in self.driver.get_meta_rules(meta_rule_id=meta_rule_id): + raise exceptions.MetaRuleUnknown + # TODO (asteroide): check and/or delete data and assignments and rules linked to that meta_rule + return self.driver.delete_meta_rule(meta_rule_id=meta_rule_id) + + @enforce("read", "meta_data") + def get_subject_categories(self, user_id, category_id=None): + return self.driver.get_subject_categories(category_id=category_id) + + @enforce(("read", "write"), "meta_data") + def add_subject_category(self, user_id, category_id=None, value=None): + if category_id in self.driver.get_subject_categories(category_id=category_id): + raise exceptions.SubjectCategoryExisting + # if not category_id: + # category_id = uuid4().hex + return self.driver.add_subject_category(name=value["name"], description=value["description"]) + + @enforce(("read", "write"), "meta_data") + def delete_subject_category(self, user_id, category_id): + # TODO (asteroide): delete all data linked to that category + # TODO (asteroide): delete all meta_rules linked to that category + if category_id not in self.driver.get_subject_categories(category_id=category_id): + raise exceptions.SubjectCategoryUnknown + return self.driver.delete_subject_category(category_id=category_id) + + @enforce("read", "meta_data") + def get_object_categories(self, user_id, category_id): + return self.driver.get_object_categories(category_id) + + @enforce(("read", "write"), "meta_data") + def add_object_category(self, user_id, category_id=None, value=None): + if category_id in self.driver.get_object_categories(category_id=category_id): + raise exceptions.ObjectCategoryExisting + # if not category_id: + # category_id = uuid4().hex + return self.driver.add_object_category(name=value["name"], description=value["description"]) + + @enforce(("read", "write"), "meta_data") + def delete_object_category(self, user_id, category_id): + # TODO (asteroide): delete all data linked to that category + # TODO (asteroide): delete all meta_rules linked to that category + if category_id not in self.driver.get_object_categories(category_id=category_id): + raise exceptions.ObjectCategoryUnknown + return self.driver.delete_object_category(category_id=category_id) + + @enforce("read", "meta_data") + def get_action_categories(self, user_id, category_id): + return self.driver.get_action_categories(category_id=category_id) + + @enforce(("read", "write"), "meta_data") + def add_action_category(self, user_id, category_id=None, value=None): + if category_id in self.driver.get_action_categories(category_id=category_id): + raise exceptions.ActionCategoryExisting + # if not category_id: + # category_id = uuid4().hex + return self.driver.add_action_category(name=value["name"], description=value["description"]) + + @enforce(("read", "write"), "meta_data") + def delete_action_category(self, user_id, category_id): + # TODO (asteroide): delete all data linked to that category + # TODO (asteroide): delete all meta_rules linked to that category + if category_id not in self.driver.get_action_categories(category_id=category_id): + raise exceptions.ActionCategoryExisting + return self.driver.delete_action_category(category_id=category_id) + diff --git a/moonv4/moon_db/moon_db/api/pdp.py b/moonv4/moon_db/moon_db/api/pdp.py new file mode 100644 index 00000000..f84c7a85 --- /dev/null +++ b/moonv4/moon_db/moon_db/api/pdp.py @@ -0,0 +1,48 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import os +import re +import types +import json +import copy +from uuid import uuid4 +from oslo_config import cfg +from oslo_log import log as logging +import requests +from moon_utilities import exceptions +from moon_utilities.security_functions import filter_input, enforce +# from moon_db.api import algorithms +from moon_db.api.managers import Managers + + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class PDPManager(Managers): + + def __init__(self, connector=None): + self.driver = connector.driver + Managers.PDPManager = self + + @enforce(("read", "write"), "pdp") + def update_pdp(self, user_id, pdp_id, value): + return self.driver.update_pdp(pdp_id=pdp_id, value=value) + + @enforce(("read", "write"), "pdp") + def delete_pdp(self, user_id, pdp_id): + return self.driver.delete_pdp(pdp_id=pdp_id) + + @enforce(("read", "write"), "pdp") + def add_pdp(self, user_id, pdp_id=None, value=None): + if not pdp_id: + pdp_id = uuid4().hex + return self.driver.add_pdp(pdp_id=pdp_id, value=value) + + @enforce("read", "pdp") + def get_pdp(self, user_id, pdp_id=None): + return self.driver.get_pdp(pdp_id=pdp_id) + diff --git a/moonv4/moon_db/moon_db/api/policy.py b/moonv4/moon_db/moon_db/api/policy.py new file mode 100644 index 00000000..73889b85 --- /dev/null +++ b/moonv4/moon_db/moon_db/api/policy.py @@ -0,0 +1,237 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import os +import re +import types +import json +import copy +from uuid import uuid4 +from oslo_config import cfg +from oslo_log import log as logging +import requests +from moon_utilities import exceptions +from moon_utilities.security_functions import filter_input, enforce +# from moon_db.api import algorithms +from moon_db.api.managers import Managers + + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class PolicyManager(Managers): + + def __init__(self, connector=None): + self.driver = connector.driver + Managers.PolicyManager = self + + @enforce(("read", "write"), "policies") + def update_policy(self, user_id, policy_id, value): + return self.driver.update_policy(policy_id=policy_id, value=value) + + @enforce(("read", "write"), "policies") + def delete_policy(self, user_id, policy_id): + # TODO (asteroide): unmap PDP linked to that policy + return self.driver.delete_policy(policy_id=policy_id) + + @enforce(("read", "write"), "policies") + def add_policy(self, user_id, policy_id=None, value=None): + if not policy_id: + policy_id = uuid4().hex + return self.driver.add_policy(policy_id=policy_id, value=value) + + @enforce("read", "policies") + def get_policies(self, user_id, policy_id=None): + return self.driver.get_policies(policy_id=policy_id) + + @enforce("read", "perimeter") + def get_subjects(self, user_id, policy_id, perimeter_id=None): + return self.driver.get_subjects(policy_id=policy_id, perimeter_id=perimeter_id) + + @enforce(("read", "write"), "perimeter") + def add_subject(self, user_id, policy_id, perimeter_id=None, value=None): + if not perimeter_id: + perimeter_id = uuid4().hex + # TODO (asteroide): must check and add Keystone ID here + return self.driver.set_subject(policy_id=policy_id, perimeter_id=perimeter_id, value=value) + + @enforce(("read", "write"), "perimeter") + def delete_subject(self, user_id, policy_id, perimeter_id): + return self.driver.delete_subject(policy_id=policy_id, perimeter_id=perimeter_id) + + @enforce("read", "perimeter") + def get_objects(self, user_id, policy_id, perimeter_id=None): + return self.driver.get_objects(policy_id=policy_id, perimeter_id=perimeter_id) + + @enforce(("read", "write"), "perimeter") + def add_object(self, user_id, policy_id, perimeter_id=None, value=None): + if not perimeter_id: + perimeter_id = uuid4().hex + return self.driver.set_object(policy_id=policy_id, perimeter_id=perimeter_id, value=value) + + @enforce(("read", "write"), "perimeter") + def delete_object(self, user_id, policy_id, perimeter_id): + return self.driver.delete_object(policy_id=policy_id, perimeter_id=perimeter_id) + + @enforce("read", "perimeter") + def get_actions(self, user_id, policy_id, perimeter_id=None): + return self.driver.get_actions(policy_id=policy_id, perimeter_id=perimeter_id) + + @enforce(("read", "write"), "perimeter") + def add_action(self, user_id, policy_id, perimeter_id=None, value=None): + if not perimeter_id: + perimeter_id = uuid4().hex + return self.driver.set_action(policy_id=policy_id, perimeter_id=perimeter_id, value=value) + + @enforce(("read", "write"), "perimeter") + def delete_action(self, user_id, policy_id, perimeter_id): + return self.driver.delete_action(policy_id=policy_id, perimeter_id=perimeter_id) + + @enforce("read", "data") + def get_subject_data(self, user_id, policy_id, data_id=None, category_id=None): + available_metadata = self.get_available_metadata(user_id, policy_id) + results = [] + if not category_id: + for cat in available_metadata["subject"]: + results.append(self.driver.get_subject_data(policy_id=policy_id, data_id=data_id, + category_id=cat)) + if category_id and category_id in available_metadata["subject"]: + results.append(self.driver.get_subject_data(policy_id=policy_id, data_id=data_id, + category_id=category_id)) + return results + + @enforce(("read", "write"), "data") + def set_subject_data(self, user_id, policy_id, data_id=None, category_id=None, value=None): + if not data_id: + data_id = uuid4().hex + return self.driver.set_subject_data(policy_id=policy_id, data_id=data_id, category_id=category_id, value=value) + + @enforce(("read", "write"), "data") + def delete_subject_data(self, user_id, policy_id, data_id): + # TODO (asteroide): check and/or delete assignments linked to that data + return self.driver.delete_subject_data(policy_id=policy_id, data_id=data_id) + + @enforce("read", "data") + def get_object_data(self, user_id, policy_id, data_id=None, category_id=None): + available_metadata = self.get_available_metadata(user_id, policy_id) + results = [] + if not category_id: + for cat in available_metadata["object"]: + results.append(self.driver.get_object_data(policy_id=policy_id, data_id=data_id, + category_id=cat)) + if category_id and category_id in available_metadata["object"]: + results.append(self.driver.get_object_data(policy_id=policy_id, data_id=data_id, + category_id=category_id)) + return results + + @enforce(("read", "write"), "data") + def add_object_data(self, user_id, policy_id, data_id=None, category_id=None, value=None): + if not data_id: + data_id = uuid4().hex + return self.driver.set_object_data(policy_id=policy_id, data_id=data_id, category_id=category_id, value=value) + + @enforce(("read", "write"), "data") + def delete_object_data(self, user_id, policy_id, data_id): + # TODO (asteroide): check and/or delete assignments linked to that data + return self.driver.delete_object_data(policy_id=policy_id, data_id=data_id) + + @enforce("read", "data") + def get_action_data(self, user_id, policy_id, data_id=None, category_id=None): + available_metadata = self.get_available_metadata(user_id, policy_id) + results = [] + if not category_id: + for cat in available_metadata["action"]: + results.append(self.driver.get_action_data(policy_id=policy_id, data_id=data_id, + category_id=cat)) + if category_id and category_id in available_metadata["action"]: + results.append(self.driver.get_action_data(policy_id=policy_id, data_id=data_id, + category_id=category_id)) + return results + + @enforce(("read", "write"), "data") + def add_action_data(self, user_id, policy_id, data_id=None, category_id=None, value=None): + if not data_id: + data_id = uuid4().hex + return self.driver.set_action_data(policy_id=policy_id, data_id=data_id, category_id=category_id, value=value) + + @enforce(("read", "write"), "data") + def delete_action_data(self, user_id, policy_id, data_id): + # TODO (asteroide): check and/or delete assignments linked to that data + return self.driver.delete_action_data(policy_id=policy_id, data_id=data_id) + + @enforce("read", "assignments") + def get_subject_assignments(self, user_id, policy_id, subject_id=None, category_id=None): + return self.driver.get_subject_assignments(policy_id=policy_id, subject_id=subject_id, category_id=category_id) + + @enforce(("read", "write"), "assignments") + def add_subject_assignment(self, user_id, policy_id, subject_id, category_id, data_id): + return self.driver.add_subject_assignment(policy_id=policy_id, subject_id=subject_id, + category_id=category_id, data_id=data_id) + + @enforce(("read", "write"), "assignments") + def delete_subject_assignment(self, user_id, policy_id, subject_id, category_id, data_id): + return self.driver.delete_subject_assignment(policy_id=policy_id, subject_id=subject_id, + category_id=category_id, data_id=data_id) + + @enforce("read", "assignments") + def get_object_assignments(self, user_id, policy_id, object_id=None, category_id=None): + return self.driver.get_object_assignments(policy_id=policy_id, object_id=object_id, category_id=category_id) + + @enforce(("read", "write"), "assignments") + def add_object_assignment(self, user_id, policy_id, object_id, category_id, data_id): + return self.driver.add_object_assignment(policy_id=policy_id, object_id=object_id, + category_id=category_id, data_id=data_id) + + @enforce(("read", "write"), "assignments") + def delete_object_assignment(self, user_id, policy_id, object_id, category_id, data_id): + return self.driver.delete_object_assignment(policy_id=policy_id, object_id=object_id, + category_id=category_id, data_id=data_id) + + @enforce("read", "assignments") + def get_action_assignments(self, user_id, policy_id, action_id=None, category_id=None): + return self.driver.get_action_assignments(policy_id=policy_id, action_id=action_id, category_id=category_id) + + @enforce(("read", "write"), "assignments") + def add_action_assignment(self, user_id, policy_id, action_id, category_id, data_id): + return self.driver.add_action_assignment(policy_id=policy_id, action_id=action_id, + category_id=category_id, data_id=data_id) + + @enforce(("read", "write"), "assignments") + def delete_action_assignment(self, user_id, policy_id, action_id, category_id, data_id): + return self.driver.delete_action_assignment(policy_id=policy_id, action_id=action_id, + category_id=category_id, data_id=data_id) + + @enforce("read", "rules") + def get_rules(self, user_id, policy_id, meta_rule_id=None, rule_id=None): + return self.driver.get_rules(policy_id=policy_id, meta_rule_id=meta_rule_id, rule_id=rule_id) + + @enforce(("read", "write"), "rules") + def add_rule(self, user_id, policy_id, meta_rule_id, value): + return self.driver.add_rule(policy_id=policy_id, meta_rule_id=meta_rule_id, value=value) + + @enforce(("read", "write"), "rules") + def delete_rule(self, user_id, policy_id, rule_id): + return self.driver.delete_rule(policy_id=policy_id, rule_id=rule_id) + + @enforce("read", "meta_data") + def get_available_metadata(self, user_id, policy_id): + categories = { + "subject": [], + "object": [], + "action": [] + } + policy = self.driver.get_policies(policy_id=policy_id) + model_id = policy[policy_id]["model_id"] + model = Managers.ModelManager.get_models(user_id=user_id, model_id=model_id) + try: + meta_rule_list = model[model_id]["meta_rules"] + for meta_rule_id in meta_rule_list: + meta_rule = Managers.ModelManager.get_meta_rules(user_id=user_id, meta_rule_id=meta_rule_id) + categories["subject"].extend(meta_rule[meta_rule_id]["subject_categories"]) + categories["object"].extend(meta_rule[meta_rule_id]["object_categories"]) + categories["action"].extend(meta_rule[meta_rule_id]["action_categories"]) + finally: + return categories diff --git a/moonv4/moon_db/moon_db/api/tenants.py b/moonv4/moon_db/moon_db/api/tenants.py new file mode 100644 index 00000000..dd7c4ec5 --- /dev/null +++ b/moonv4/moon_db/moon_db/api/tenants.py @@ -0,0 +1,137 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from uuid import uuid4 +from moon_utilities import exceptions +from moon_db.api.managers import Managers +from moon_utilities.security_functions import filter_input, enforce +from oslo_log import log as logging + +LOG = logging.getLogger(__name__) + + +class TenantManager(Managers): + + def __init__(self, connector=None): + self.driver = connector.driver + Managers.TenantManager = self + + @filter_input + @enforce("read", "tenants") + def get_tenants_dict(self, user_id): + """ + Return a dictionary with all tenants + :return: { + tenant_id1: { + name: xxx, + description: yyy, + intra_authz_extension_id: zzz, + intra_admin_extension_id: zzz, + }, + tenant_id2: {...}, + ... + } + """ + return self.driver.get_tenants_dict() + + def __get_keystone_tenant_dict(self, tenant_id="", tenant_name=""): + tenants = Managers.KeystoneManager.list_projects() + for tenant in tenants: + if tenant_id and tenant_id == tenant['id']: + return tenant + if tenant_name and tenant_name == tenant['name']: + return tenant + if not tenant_id: + tenant_id = uuid4().hex + if not tenant_name: + tenant_name = tenant_id + tenant = { + "id": tenant_id, + "name": tenant_name, + "description": "Auto generated tenant from Moon platform", + "enabled": True, + "domain_id": "default" + } + keystone_tenant = Managers.KeystoneManager.create_project(tenant["id"], tenant) + return keystone_tenant + + @filter_input + @enforce(("read", "write"), "tenants") + def add_tenant_dict(self, user_id, tenant_id, tenant_dict): + tenants_dict = self.driver.get_tenants_dict() + for tenant_id in tenants_dict: + if tenants_dict[tenant_id]['name'] == tenant_dict['name']: + raise exceptions.TenantAddedNameExisting() + + # Check (and eventually sync) Keystone tenant + if 'id' not in tenant_dict: + tenant_dict['id'] = None + keystone_tenant = self.__get_keystone_tenant_dict(tenant_dict['id'], tenant_dict['name']) + for att in keystone_tenant: + if keystone_tenant[att]: + tenant_dict[att] = keystone_tenant[att] + # Sync users between intra_authz_extension and intra_admin_extension + LOG.debug("add_tenant_dict {}".format(tenant_dict)) + if 'intra_admin_extension_id' in tenant_dict and tenant_dict['intra_admin_extension_id']: + if 'intra_authz_extension_id' in tenant_dict and tenant_dict['intra_authz_extension_id']: + authz_subjects_dict = Managers.IntraExtensionAdminManager.get_subjects_dict( + Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_authz_extension_id']) + authz_subject_names_list = [authz_subjects_dict[subject_id]["name"] for subject_id in authz_subjects_dict] + admin_subjects_dict = Managers.IntraExtensionAdminManager.get_subjects_dict( + Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_admin_extension_id']) + admin_subject_names_list = [admin_subjects_dict[subject_id]["name"] for subject_id in admin_subjects_dict] + for _subject_id in authz_subjects_dict: + if authz_subjects_dict[_subject_id]["name"] not in admin_subject_names_list: + Managers.IntraExtensionAdminManager.add_subject_dict( + Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_admin_extension_id'], authz_subjects_dict[_subject_id]) + for _subject_id in admin_subjects_dict: + if admin_subjects_dict[_subject_id]["name"] not in authz_subject_names_list: + Managers.IntraExtensionAdminManager.add_subject_dict( + Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_authz_extension_id'], admin_subjects_dict[_subject_id]) + + return self.driver.add_tenant_dict(tenant_dict['id'], tenant_dict) + + @filter_input + @enforce("read", "tenants") + def get_tenant_dict(self, user_id, tenant_id): + tenants_dict = self.driver.get_tenants_dict() + if tenant_id not in tenants_dict: + raise exceptions.TenantUnknown() + return tenants_dict[tenant_id] + + @filter_input + @enforce(("read", "write"), "tenants") + def del_tenant(self, user_id, tenant_id): + if tenant_id not in self.driver.get_tenants_dict(): + raise exceptions.TenantUnknown() + self.driver.del_tenant(tenant_id) + + @filter_input + @enforce(("read", "write"), "tenants") + def set_tenant_dict(self, user_id, tenant_id, tenant_dict): + tenants_dict = self.driver.get_tenants_dict() + if tenant_id not in tenants_dict: + raise exceptions.TenantUnknown() + + # Sync users between intra_authz_extension and intra_admin_extension + if 'intra_admin_extension_id' in tenant_dict: + if 'intra_authz_extension_id' in tenant_dict: + authz_subjects_dict = Managers.IntraExtensionAdminManager.get_subjects_dict( + Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_authz_extension_id']) + authz_subject_names_list = [authz_subjects_dict[subject_id]["name"] for subject_id in authz_subjects_dict] + admin_subjects_dict = Managers.IntraExtensionAdminManager.get_subjects_dict( + Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_admin_extension_id']) + admin_subject_names_list = [admin_subjects_dict[subject_id]["name"] for subject_id in admin_subjects_dict] + for _subject_id in authz_subjects_dict: + if authz_subjects_dict[_subject_id]["name"] not in admin_subject_names_list: + Managers.IntraExtensionAdminManager.add_subject_dict( + Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_admin_extension_id'], authz_subjects_dict[_subject_id]) + for _subject_id in admin_subjects_dict: + if admin_subjects_dict[_subject_id]["name"] not in authz_subject_names_list: + Managers.IntraExtensionAdminManager.add_subject_dict( + Managers.IntraExtensionRootManager.root_admin_id, tenant_dict['intra_authz_extension_id'], admin_subjects_dict[_subject_id]) + + return self.driver.set_tenant_dict(tenant_id, tenant_dict) + diff --git a/moonv4/moon_db/moon_db/backends/__init__.py b/moonv4/moon_db/moon_db/backends/__init__.py new file mode 100644 index 00000000..237bdc3e --- /dev/null +++ b/moonv4/moon_db/moon_db/backends/__init__.py @@ -0,0 +1,97 @@ + +""" +intra_extensions = { + intra_extension_id1: { + name: xxx, + model: yyy, + description: zzz}, + intra_extension_id2: {...}, + ... +} + +tenants = { + tenant_id1: { + name: xxx, + description: yyy, + intra_authz_extension_id: zzz, + intra_admin_extension_id: zzz, + }, + tenant_id2: {...}, + ... +} + +--------------- for each intra-extension ----------------- + +subject_categories = { + subject_category_id1: { + name: xxx, + description: yyy}, + subject_category_id2: {...}, + ... +} + +subjects = { + subject_id1: { + name: xxx, + description: yyy, + ...}, + subject_id2: {...}, + ... +} + +subject_scopes = { + subject_category_id1: { + subject_scope_id1: { + name: xxx, + description: aaa}, + subject_scope_id2: { + name: yyy, + description: bbb}, + ...}, + subject_scope_id3: { + ...} + subject_category_id2: {...}, + ... +} + +subject_assignments = { + subject_id1: { + subject_category_id1: [subject_scope_id1, subject_scope_id2, ...], + subject_category_id2: [subject_scope_id3, subject_scope_id4, ...], + ... + }, + subject_id2: { + subject_category_id1: [subject_scope_id1, subject_scope_id2, ...], + subject_category_id2: [subject_scope_id3, subject_scope_id4, ...], + ... + }, + ... +} + +aggregation_algorithm = { + aggregation_algorithm_id: { + name: xxx, + description: yyy + } + } + +sub_meta_rules = { + sub_meta_rule_id_1: { + "name": xxx, + "algorithm": yyy, + "subject_categories": [subject_category_id1, subject_category_id2,...], + "object_categories": [object_category_id1, object_category_id2,...], + "action_categories": [action_category_id1, action_category_id2,...] + sub_meta_rule_id_2: {...}, + ... +} + +rules = { + sub_meta_rule_id1: { + rule_id1: [subject_scope1, subject_scope2, ..., action_scope1, ..., object_scope1, ... ], + rule_id2: [subject_scope3, subject_scope4, ..., action_scope3, ..., object_scope3, ... ], + rule_id3: [thomas, write, admin.subjects] + ...}, + sub_meta_rule_id2: { }, + ...} +""" \ No newline at end of file diff --git a/moonv4/moon_db/moon_db/backends/flat.py b/moonv4/moon_db/moon_db/backends/flat.py new file mode 100644 index 00000000..820a4146 --- /dev/null +++ b/moonv4/moon_db/moon_db/backends/flat.py @@ -0,0 +1,89 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import logging +import time +from moon_db.core import LogDriver + + +class LogConnector(LogDriver): + + AUTHZ_FILE = '/var/log/moon/authz.log' + SYS_FILE = '/var/log/moon/system.log' + TIME_FORMAT = '%Y-%m-%d-%H:%M:%S' + + def __init__(self): + # Fixme (dthom): when logging from an other class, the %appname% in the event + # is always keystone.contrib.moon.backends.flat + super(LogConnector, self).__init__() + + self.SYS_LOG = logging.getLogger(__name__) + if not len(self.SYS_LOG.handlers): + fh = logging.FileHandler(self.SYS_FILE) + fh.setLevel(logging.DEBUG) + formatter = logging.Formatter('%(asctime)s ------ %(message)s', self.TIME_FORMAT) + fh.setFormatter(formatter) + self.SYS_LOG.addHandler(fh) + + self.AUTHZ_LOG = logging.getLogger("authz") + if not len(self.AUTHZ_LOG.handlers): + fh = logging.FileHandler(self.AUTHZ_FILE) + fh.setLevel(logging.WARNING) + formatter = logging.Formatter('%(asctime)s ------ %(message)s', self.TIME_FORMAT) + fh.setFormatter(formatter) + self.AUTHZ_LOG.addHandler(fh) + + def authz(self, message): + self.AUTHZ_LOG.warn(message) + + def debug(self, message): + self.SYS_LOG.debug(message) + + def info(self, message): + self.SYS_LOG.info(message) + + def warning(self, message): + self.SYS_LOG.warning(message) + + def error(self, message): + self.SYS_LOG.error(message) + + def critical(self, message): + self.SYS_LOG.critical(message) + + def get_logs(self, logger="authz", event_number=None, time_from=None, time_to=None, filter_str=None): + if logger == "authz": + _logs = open(self.AUTHZ_FILE).readlines() + else: + _logs = open(self.SYS_FILE).readlines() + if filter_str: + _logs = filter(lambda x: filter_str in x, _logs) + if time_from: + if isinstance(time_from, str): + time_from = time.strptime(time_from.split(" ")[0], self.TIME_FORMAT) + try: + __logs = [] + for log in _logs: + _log = time.strptime(log.split(" ")[0], self.TIME_FORMAT) + if time_from <= _log: + __logs.append(log) + _logs = __logs + except ValueError: + self.error("Time format error") + if time_to: + try: + if isinstance(time_to, str): + time_to = time.strptime(time_to.split(" ")[0], self.TIME_FORMAT) + __logs = [] + for log in _logs: + _log = time.strptime(log.split(" ")[0], self.TIME_FORMAT) + if time_to >= _log: + __logs.append(log) + _logs = __logs + except ValueError: + self.error("Time format error") + if event_number: + _logs = _logs[-event_number:] + return list(_logs) diff --git a/moonv4/moon_db/moon_db/backends/memory.py b/moonv4/moon_db/moon_db/backends/memory.py new file mode 100644 index 00000000..06de99eb --- /dev/null +++ b/moonv4/moon_db/moon_db/backends/memory.py @@ -0,0 +1,60 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import os +import json +import logging +import hashlib +from glob import glob +from oslo_config import cfg +from moon_db.core import ConfigurationDriver + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +class ConfigurationConnector(object): + + def __init__(self, engine): + super(ConfigurationConnector, self).__init__() + self.policy_directory = CONF.policy_directory + self.aggregation_algorithms_dict = dict() + self.aggregation_algorithms_dict[hashlib.sha224("all_true".encode("utf-8")).hexdigest()[:32]] = \ + {'name': 'all_true', 'description': 'all rules must match'} + self.aggregation_algorithms_dict[hashlib.sha224("one_true".encode("utf-8")).hexdigest()[:32]] = \ + {'name': 'one_true', 'description': 'only one rule has to match'} + self.sub_meta_rule_algorithms_dict = dict() + self.sub_meta_rule_algorithms_dict[hashlib.sha224("inclusion".encode("utf-8")).hexdigest()[:32]] = \ + {'name': 'inclusion', 'description': 'inclusion'} + self.sub_meta_rule_algorithms_dict[hashlib.sha224("comparison".encode("utf-8")).hexdigest()[:32]] = \ + {'name': 'comparison', 'description': 'comparison'} + + def get_policy_templates_dict(self): + """ + :return: { + template_id1: {name: template_name, description: template_description}, + template_id2: {name: template_name, description: template_description}, + ... + } + """ + nodes = glob(os.path.join(self.policy_directory, "*")) + LOG.info("get_policy_templates_dict {} {}".format(self.policy_directory, nodes)) + templates = dict() + for node in nodes: + try: + metadata = json.load(open(os.path.join(node, "metadata.json"))) + except IOError: + # Note (asteroide): it's not a true policy directory, so we forgive it + continue + templates[os.path.basename(node)] = dict() + templates[os.path.basename(node)]["name"] = metadata["name"] + templates[os.path.basename(node)]["description"] = metadata["description"] + return templates + + def get_aggregation_algorithms_dict(self): + return self.aggregation_algorithms_dict + + def get_sub_meta_rule_algorithms_dict(self): + return self.sub_meta_rule_algorithms_dict diff --git a/moonv4/moon_db/moon_db/backends/sql.py b/moonv4/moon_db/moon_db/backends/sql.py new file mode 100644 index 00000000..69132116 --- /dev/null +++ b/moonv4/moon_db/moon_db/backends/sql.py @@ -0,0 +1,1877 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import copy +import json +from uuid import uuid4 +from moon_db.exception import * +from moon_db.core import PDPDriver, PolicyDriver, ModelDriver +import sqlalchemy as sql +import logging +from sqlalchemy.orm import sessionmaker +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy import create_engine +from contextlib import contextmanager +from sqlalchemy import types as sql_types +from oslo_config import cfg +# from moon_utilities.exceptions import IntraExtensionUnknown + +# from sqlalchemy.orm.exc import UnmappedInstanceError +# from keystone.contrib.moon import InterExtensionDriver + +CONF = cfg.CONF +LOG = logging.getLogger(__name__) +Base = declarative_base() + + +class DictBase: + attributes = [] + + @classmethod + def from_dict(cls, d): + new_d = d.copy() + return cls(**new_d) + # new_d = d.copy() + # + # new_d['extra'] = {k: new_d.pop(k) for k in six.iterkeys(d) + # if k not in cls.attributes and k != 'extra'} + # + # return cls(**new_d) + + def to_dict(self): + d = dict() + for attr in self.__class__.attributes: + d[attr] = getattr(self, attr) + return d + + def __getitem__(self, key): + # if "extra" in dir(self) and key in self.extra: + # return self.extra[key] + return getattr(self, key) + + +class JsonBlob(sql_types.TypeDecorator): + + impl = sql.Text + + def process_bind_param(self, value, dialect): + return json.dumps(value) + + def process_result_value(self, value, dialect): + return json.loads(value) + + +class Model(Base, DictBase): + __tablename__ = 'models' + attributes = ['id', 'value'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + + def to_dict(self): + return { + "name": self.value.get("name"), + "description": self.value.get("description", ""), + "meta_rules": self.value.get("meta_rules", list()), + } + + +class Policy(Base, DictBase): + __tablename__ = 'policies' + attributes = ['id', 'value'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + + def to_dict(self): + return { + "name": self.value.get("name"), + "description": self.value.get("description", ""), + "model_id": self.value.get("model_id", ""), + "genre": self.value.get("genre", ""), + } + + +class PDP(Base, DictBase): + __tablename__ = 'pdp' + attributes = ['id', 'value'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + + def to_dict(self): + return { + "name": self.value.get("name"), + "description": self.value.get("description", ""), + "keystone_project_id": self.value.get("keystone_project_id", ""), + "security_pipeline": self.value.get("security_pipeline", []), + } + + +class SubjectCategory(Base, DictBase): + __tablename__ = 'subject_categories' + attributes = ['id', 'name', 'description'] + id = sql.Column(sql.String(64), primary_key=True) + name = sql.Column(sql.String(256), nullable=False) + description = sql.Column(sql.String(256), nullable=True) + + +class ObjectCategory(Base, DictBase): + __tablename__ = 'object_categories' + attributes = ['id', 'name', 'description'] + id = sql.Column(sql.String(64), primary_key=True) + name = sql.Column(sql.String(256), nullable=False) + description = sql.Column(sql.String(256), nullable=True) + + +class ActionCategory(Base, DictBase): + __tablename__ = 'action_categories' + attributes = ['id', 'name', 'description'] + id = sql.Column(sql.String(64), primary_key=True) + name = sql.Column(sql.String(256), nullable=False) + description = sql.Column(sql.String(256), nullable=True) + + +class Subject(Base, DictBase): + __tablename__ = 'subjects' + attributes = ['id', 'value'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + + def __repr__(self): + return "{}: {}".format(self.id, json.dumps(self.value)) + + def to_return(self): + return { + 'id': self.id, + 'name': self.value.get("name", ""), + 'description': self.value.get("description", ""), + 'email': self.value.get("email", ""), + 'partner_id': self.value.get("partner_id", ""), + 'policy_list': self.value.get("policy_list", []) + } + + def to_dict(self): + return { + 'id': self.id, + 'value': self.value + } + + +class Object(Base, DictBase): + __tablename__ = 'objects' + attributes = ['id', 'value'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + + def __repr__(self): + return "{}: {}".format(self.id, json.dumps(self.value)) + + def to_dict(self): + return { + 'id': self.id, + 'value': self.value + } + + def to_return(self): + return { + 'id': self.id, + 'name': self.value.get("name", ""), + 'description': self.value.get("description", ""), + 'partner_id': self.value.get("partner_id", ""), + 'policy_list': self.value.get("policy_list", []) + } + + +class Action(Base, DictBase): + __tablename__ = 'actions' + attributes = ['id', 'value'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + + def __repr__(self): + return "{}: {}".format(self.id, json.dumps(self.value)) + + def to_dict(self): + return { + 'id': self.id, + 'value': self.value + } + + def to_return(self): + return { + 'id': self.id, + 'name': self.value.get("name", ""), + 'description': self.value.get("description", ""), + 'partner_id': self.value.get("partner_id", ""), + 'policy_list': self.value.get("policy_list", []) + } + + +class SubjectData(Base, DictBase): + __tablename__ = 'subject_data' + attributes = ['id', 'value', 'category_id', 'policy_id'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + category_id = sql.Column(sql.ForeignKey("subject_categories.id"), nullable=False) + policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False) + + def to_dict(self): + return { + 'id': self.id, + 'name': self.value.get("name", ""), + 'description': self.value.get("description", ""), + 'category_id': self.category_id, + 'policy_id': self.policy_id + } + + +class ObjectData(Base, DictBase): + __tablename__ = 'object_data' + attributes = ['id', 'value', 'category_id', 'policy_id'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + category_id = sql.Column(sql.ForeignKey("object_categories.id"), nullable=False) + policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False) + + +class ActionData(Base, DictBase): + __tablename__ = 'action_data' + attributes = ['id', 'value', 'category_id', 'policy_id'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + category_id = sql.Column(sql.ForeignKey("action_categories.id"), nullable=False) + policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False) + + +class SubjectAssignment(Base, DictBase): + __tablename__ = 'subject_assignments' + attributes = ['id', 'assignments', 'policy_id', 'subject_id', 'category_id'] + id = sql.Column(sql.String(64), primary_key=True) + assignments = sql.Column(JsonBlob(), nullable=True) + policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False) + subject_id = sql.Column(sql.ForeignKey("subjects.id"), nullable=False) + category_id = sql.Column(sql.ForeignKey("subject_categories.id"), nullable=False) + + def to_dict(self): + return { + "id": self.id, + "policy_id": self.policy_id, + "subject_id": self.subject_id, + "category_id": self.category_id, + "assignments": self.assignments, + } + + +class ObjectAssignment(Base, DictBase): + __tablename__ = 'object_assignments' + attributes = ['id', 'assignments', 'policy_id', 'object_id', 'category_id'] + id = sql.Column(sql.String(64), primary_key=True) + assignments = sql.Column(JsonBlob(), nullable=True) + policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False) + object_id = sql.Column(sql.ForeignKey("objects.id"), nullable=False) + category_id = sql.Column(sql.ForeignKey("object_categories.id"), nullable=False) + + def to_dict(self): + return { + "id": self.id, + "policy_id": self.policy_id, + "object_id": self.object_id, + "category_id": self.category_id, + "assignments": self.assignments, + } + + +class ActionAssignment(Base, DictBase): + __tablename__ = 'action_assignments' + attributes = ['id', 'assignments', 'policy_id', 'action_id', 'category_id'] + id = sql.Column(sql.String(64), primary_key=True) + assignments = sql.Column(JsonBlob(), nullable=True) + policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False) + action_id = sql.Column(sql.ForeignKey("actions.id"), nullable=False) + category_id = sql.Column(sql.ForeignKey("action_categories.id"), nullable=False) + + def to_dict(self): + return { + "id": self.id, + "policy_id": self.policy_id, + "action_id": self.action_id, + "category_id": self.category_id, + "assignments": self.assignments, + } + + +class MetaRule(Base, DictBase): + __tablename__ = 'meta_rules' + attributes = ['id', 'value'] + id = sql.Column(sql.String(64), primary_key=True) + value = sql.Column(JsonBlob(), nullable=True) + + def to_dict(self): + return { + "name": self.value["name"], + "description": self.value.get("description", ""), + "subject_categories": self.value.get("subject_categories", list()), + "object_categories": self.value.get("object_categories", list()), + "action_categories": self.value.get("action_categories", list()), + } + + +class Rule(Base, DictBase): + __tablename__ = 'rules' + attributes = ['id', 'rule', 'policy_id', 'meta_rule_id'] + id = sql.Column(sql.String(64), primary_key=True) + rule = sql.Column(JsonBlob(), nullable=True) + policy_id = sql.Column(sql.ForeignKey("policies.id"), nullable=False) + meta_rule_id = sql.Column(sql.ForeignKey("meta_rules.id"), nullable=False) + + def to_dict(self): + return { + 'id': self.id, + 'rule': self.rule["rule"], + 'enabled': self.rule["enabled"], + 'policy_id': self.policy_id, + 'meta_rule_id': self.meta_rule_id + } + + def __repr__(self): + return "{}".format(self.rule) + + +@contextmanager +def session_scope(engine): + """Provide a transactional scope around a series of operations.""" + if type(engine) is str: + echo = True if CONF.debug else False + engine = create_engine(engine, echo=echo) + session = sessionmaker(bind=engine)() + try: + yield session + session.commit() + except: + session.rollback() + raise + finally: + session.close() + + +class BaseConnector(object): + """Provide a base connector to connect them all""" + engine = "" + + def __init__(self, engine_name): + echo = True if CONF.debug else False + self.engine = create_engine(engine_name, echo=echo) + + def init_db(self): + Base.metadata.create_all(self.engine) + + def set_engine(self, engine_name): + self.engine = engine_name + + def get_session(self): + return session_scope(self.engine) + + def get_session_for_read(self): + return self.get_session() + + def get_session_for_write(self): + return self.get_session() + + +class PDPConnector(BaseConnector, PDPDriver): + + def update_pdp(self, pdp_id, value): + with self.get_session_for_write() as session: + query = session.query(PDP) + query = query.filter_by(id=pdp_id) + ref = query.first() + if ref: + d = dict(ref.value) + d.update(value) + setattr(ref, "value", d) + return {ref.id: ref.to_dict()} + + def delete_pdp(self, pdp_id): + with self.get_session_for_write() as session: + ref = session.query(PDP).get(pdp_id) + session.delete(ref) + + def add_pdp(self, pdp_id=None, value=None): + with self.get_session_for_write() as session: + new = PDP.from_dict({ + "id": pdp_id if pdp_id else uuid4().hex, + "value": value + }) + session.add(new) + return {new.id: new.to_dict()} + + def get_pdp(self, pdp_id=None): + with self.get_session_for_read() as session: + query = session.query(PDP) + if pdp_id: + query = query.filter_by(id=pdp_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + +class PolicyConnector(BaseConnector, PolicyDriver): + + def update_policy(self, policy_id, value): + with self.get_session_for_write() as session: + query = session.query(Policy) + query = query.filter_by(id=policy_id) + ref = query.first() + if ref: + d = dict(ref.value) + d.update(value) + setattr(ref, "value", d) + return {ref.id: ref.to_dict()} + + def delete_policy(self, policy_id): + with self.get_session_for_write() as session: + ref = session.query(Policy).get(policy_id) + session.delete(ref) + + def add_policy(self, policy_id=None, value=None): + with self.get_session_for_write() as session: + new = Policy.from_dict({ + "id": policy_id if policy_id else uuid4().hex, + "value": value + }) + session.add(new) + return {new.id: new.to_dict()} + + def get_policies(self, policy_id=None): + with self.get_session_for_read() as session: + query = session.query(Policy) + if policy_id: + query = query.filter_by(id=policy_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def get_subjects(self, policy_id, perimeter_id=None): + with self.get_session_for_read() as session: + query = session.query(Subject) + ref_list = copy.deepcopy(query.all()) + if perimeter_id: + for _ref in ref_list: + _ref_value = _ref.to_return() + if perimeter_id == _ref.id: + if policy_id and policy_id in _ref_value["policy_list"]: + return {_ref.id: _ref_value} + else: + return {} + elif policy_id: + results = [] + for _ref in ref_list: + _ref_value = _ref.to_return() + if policy_id in _ref_value["policy_list"]: + results.append(_ref) + return {_ref.id: _ref.to_return() for _ref in results} + return {_ref.id: _ref.to_return() for _ref in ref_list} + + def set_subject(self, policy_id, perimeter_id=None, value=None): + _subject = None + with self.get_session_for_write() as session: + if perimeter_id: + query = session.query(Subject) + query = query.filter_by(id=perimeter_id) + _subject = query.first() + if not _subject: + if "policy_list" not in value or type(value["policy_list"]) is not list: + value["policy_list"] = [] + if policy_id and policy_id not in value["policy_list"]: + value["policy_list"] = [policy_id, ] + new = Subject.from_dict({ + "id": perimeter_id if perimeter_id else uuid4().hex, + "value": value + }) + session.add(new) + return {new.id: new.to_return()} + else: + _value = copy.deepcopy(_subject.to_dict()) + if "policy_list" not in _value["value"] or type(_value["value"]["policy_list"]) is not list: + _value["value"]["policy_list"] = [] + if policy_id and policy_id not in _value["value"]["policy_list"]: + _value["value"]["policy_list"] = [policy_id, ] + new_subject = Subject.from_dict(_value) + # setattr(_subject, "value", _value["value"]) + setattr(_subject, "value", getattr(new_subject, "value")) + return {_subject.id: _subject.to_return()} + + def delete_subject(self, policy_id, perimeter_id): + with self.get_session_for_write() as session: + query = session.query(Subject) + query = query.filter_by(id=perimeter_id) + _subject = query.first() + if not _subject: + raise SubjectUnknown + old_subject = copy.deepcopy(_subject.to_dict()) + # value = _subject.to_dict() + try: + old_subject["value"]["policy_list"].remove(policy_id) + new_user = Subject.from_dict(old_subject) + setattr(_subject, "value", getattr(new_user, "value")) + except ValueError: + if not _subject.value["policy_list"]: + session.delete(_subject) + + def get_objects(self, policy_id, perimeter_id=None): + with self.get_session_for_read() as session: + query = session.query(Object) + ref_list = copy.deepcopy(query.all()) + if perimeter_id: + for _ref in ref_list: + _ref_value = _ref.to_return() + if perimeter_id == _ref.id: + if policy_id and policy_id in _ref_value["policy_list"]: + return {_ref.id: _ref_value} + else: + return {} + elif policy_id: + results = [] + for _ref in ref_list: + _ref_value = _ref.to_return() + if policy_id in _ref_value["policy_list"]: + results.append(_ref) + return {_ref.id: _ref.to_return() for _ref in results} + return {_ref.id: _ref.to_return() for _ref in ref_list} + + def set_object(self, policy_id, perimeter_id=None, value=None): + _object = None + with self.get_session_for_write() as session: + if perimeter_id: + query = session.query(Object) + query = query.filter_by(id=perimeter_id) + _object = query.first() + if not _object: + if "policy_list" not in value or type(value["policy_list"]) is not list: + value["policy_list"] = [] + if policy_id and policy_id not in value["policy_list"]: + value["policy_list"] = [policy_id, ] + new = Object.from_dict({ + "id": perimeter_id if perimeter_id else uuid4().hex, + "value": value + }) + session.add(new) + return {new.id: new.to_return()} + else: + _value = copy.deepcopy(_object.to_dict()) + if "policy_list" not in _value["value"] or type(_value["value"]["policy_list"]) is not list: + _value["value"]["policy_list"] = [] + if policy_id and policy_id not in _value["value"]["policy_list"]: + _value["value"]["policy_list"] = [policy_id, ] + new_object = Object.from_dict(_value) + # setattr(_object, "value", _value["value"]) + setattr(_object, "value", getattr(new_object, "value")) + return {_object.id: _object.to_return()} + + def delete_object(self, policy_id, perimeter_id): + with self.get_session_for_write() as session: + query = session.query(Object) + query = query.filter_by(id=perimeter_id) + _object = query.first() + if not _object: + raise ObjectUnknown + old_object = copy.deepcopy(_object.to_dict()) + # value = _object.to_dict() + try: + old_object["value"]["policy_list"].remove(policy_id) + new_user = Object.from_dict(old_object) + setattr(_object, "value", getattr(new_user, "value")) + except ValueError: + if not _object.value["policy_list"]: + session.delete(_object) + + def get_actions(self, policy_id, perimeter_id=None): + with self.get_session_for_read() as session: + query = session.query(Action) + ref_list = copy.deepcopy(query.all()) + if perimeter_id: + for _ref in ref_list: + _ref_value = _ref.to_return() + if perimeter_id == _ref.id: + if policy_id and policy_id in _ref_value["policy_list"]: + return {_ref.id: _ref_value} + else: + return {} + elif policy_id: + results = [] + for _ref in ref_list: + _ref_value = _ref.to_return() + if policy_id in _ref_value["policy_list"]: + results.append(_ref) + return {_ref.id: _ref.to_return() for _ref in results} + return {_ref.id: _ref.to_return() for _ref in ref_list} + + def set_action(self, policy_id, perimeter_id=None, value=None): + _action = None + with self.get_session_for_write() as session: + if perimeter_id: + query = session.query(Action) + query = query.filter_by(id=perimeter_id) + _action = query.first() + if not _action: + if "policy_list" not in value or type(value["policy_list"]) is not list: + value["policy_list"] = [] + if policy_id and policy_id not in value["policy_list"]: + value["policy_list"] = [policy_id, ] + new = Action.from_dict({ + "id": perimeter_id if perimeter_id else uuid4().hex, + "value": value + }) + session.add(new) + return {new.id: new.to_return()} + else: + _value = copy.deepcopy(_action.to_dict()) + if "policy_list" not in _value["value"] or type(_value["value"]["policy_list"]) is not list: + _value["value"]["policy_list"] = [] + if policy_id and policy_id not in _value["value"]["policy_list"]: + _value["value"]["policy_list"] = [policy_id, ] + new_action = Action.from_dict(_value) + # setattr(_action, "value", _value["value"]) + setattr(_action, "value", getattr(new_action, "value")) + return {_action.id: _action.to_return()} + + def delete_action(self, policy_id, perimeter_id): + with self.get_session_for_write() as session: + query = session.query(Action) + query = query.filter_by(id=perimeter_id) + _action = query.first() + if not _action: + raise ActionUnknown + old_action = copy.deepcopy(_action.to_dict()) + # value = _action.to_dict() + try: + old_action["value"]["policy_list"].remove(policy_id) + new_user = Action.from_dict(old_action) + setattr(_action, "value", getattr(new_user, "value")) + except ValueError: + if not _action.value["policy_list"]: + session.delete(_action) + + def get_subject_data(self, policy_id, data_id=None, category_id=None): + with self.get_session_for_read() as session: + query = session.query(SubjectData) + if data_id: + query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id) + else: + query = query.filter_by(policy_id=policy_id, category_id=category_id) + ref_list = query.all() + return { + "policy_id": policy_id, + "category_id": category_id, + "data": {_ref.id: _ref.to_dict() for _ref in ref_list} + } + + def set_subject_data(self, policy_id, data_id=None, category_id=None, value=None): + with self.get_session_for_write() as session: + query = session.query(SubjectData) + query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id) + ref = query.first() + if not ref: + new_ref = SubjectData.from_dict( + { + "id": data_id if data_id else uuid4().hex, + 'value': value, + 'category_id': category_id, + 'policy_id': policy_id, + } + ) + session.add(new_ref) + ref = new_ref + else: + for attr in Subject.attributes: + if attr != 'id': + setattr(ref, attr, getattr(ref, attr)) + # session.flush() + return { + "policy_id": policy_id, + "category_id": category_id, + "data": {ref.id: ref.to_dict()} + } + + def delete_subject_data(self, policy_id, data_id): + with self.get_session_for_write() as session: + query = session.query(SubjectData) + query = query.filter_by(policy_id=policy_id, id=data_id) + ref = query.first() + if ref: + session.delete(ref) + + def get_object_data(self, policy_id, data_id=None, category_id=None): + with self.get_session_for_read() as session: + query = session.query(ObjectData) + if data_id: + query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id) + else: + query = query.filter_by(policy_id=policy_id, category_id=category_id) + ref_list = query.all() + return { + "policy_id": policy_id, + "category_id": category_id, + "data": {_ref.id: _ref.to_dict() for _ref in ref_list} + } + + def set_object_data(self, policy_id, data_id=None, category_id=None, value=None): + with self.get_session_for_write() as session: + query = session.query(ObjectData) + query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id) + ref = query.first() + if not ref: + new_ref = ObjectData.from_dict( + { + "id": data_id if data_id else uuid4().hex, + 'value': value, + 'category_id': category_id, + 'policy_id': policy_id, + } + ) + session.add(new_ref) + ref = new_ref + else: + for attr in Object.attributes: + if attr != 'id': + setattr(ref, attr, getattr(ref, attr)) + # session.flush() + return { + "policy_id": policy_id, + "category_id": category_id, + "data": {ref.id: ref.to_dict()} + } + + def delete_object_data(self, policy_id, data_id): + with self.get_session_for_write() as session: + query = session.query(ObjectData) + query = query.filter_by(policy_id=policy_id, id=data_id) + ref = query.first() + if ref: + session.delete(ref) + + def get_action_data(self, policy_id, data_id=None, category_id=None): + with self.get_session_for_read() as session: + query = session.query(ActionData) + if data_id: + query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id) + else: + query = query.filter_by(policy_id=policy_id, category_id=category_id) + ref_list = query.all() + return { + "policy_id": policy_id, + "category_id": category_id, + "data": {_ref.id: _ref.to_dict() for _ref in ref_list} + } + + def set_action_data(self, policy_id, data_id=None, category_id=None, value=None): + with self.get_session_for_write() as session: + query = session.query(ActionData) + query = query.filter_by(policy_id=policy_id, id=data_id, category_id=category_id) + ref = query.first() + if not ref: + new_ref = ActionData.from_dict( + { + "id": data_id if data_id else uuid4().hex, + 'value': value, + 'category_id': category_id, + 'policy_id': policy_id, + } + ) + session.add(new_ref) + ref = new_ref + else: + for attr in Action.attributes: + if attr != 'id': + setattr(ref, attr, getattr(ref, attr)) + # session.flush() + return { + "policy_id": policy_id, + "category_id": category_id, + "data": {ref.id: ref.to_dict()} + } + + def delete_action_data(self, policy_id, data_id): + with self.get_session_for_write() as session: + query = session.query(ActionData) + query = query.filter_by(policy_id=policy_id, id=data_id) + ref = query.first() + if ref: + session.delete(ref) + + def get_subject_assignments(self, policy_id, subject_id=None, category_id=None): + with self.get_session_for_write() as session: + query = session.query(SubjectAssignment) + if subject_id and category_id: + query = query.filter_by(policy_id=policy_id, subject_id=subject_id, category_id=category_id) + elif subject_id: + query = query.filter_by(policy_id=policy_id, subject_id=subject_id) + else: + query = query.filter_by(policy_id=policy_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def add_subject_assignment(self, policy_id, subject_id, category_id, data_id): + with self.get_session_for_write() as session: + query = session.query(SubjectAssignment) + query = query.filter_by(policy_id=policy_id, subject_id=subject_id, category_id=category_id) + ref = query.first() + if ref: + old_ref = copy.deepcopy(ref.to_dict()) + assignments = old_ref["assignments"] + assignments.append(data_id) + setattr(ref, "assignments", assignments) + else: + ref = SubjectAssignment.from_dict( + { + "id": uuid4().hex, + "policy_id": policy_id, + "subject_id": subject_id, + "category_id": category_id, + "assignments": [data_id, ], + } + ) + session.add(ref) + return {ref.id: ref.to_dict()} + + def delete_subject_assignment(self, policy_id, subject_id, category_id, data_id): + with self.get_session_for_write() as session: + query = session.query(SubjectAssignment) + query = query.filter_by(policy_id=policy_id, subject_id=subject_id, category_id=category_id) + ref = query.first() + if ref: + old_ref = copy.deepcopy(ref.to_dict()) + assignments = old_ref["assignments"] + # TODO (asteroide): if data_id is None, delete all + if data_id in assignments: + assignments.remove(data_id) + # FIXME (asteroide): the setattr doesn't work here ; the assignments is not updated in the database + setattr(ref, "assignments", assignments) + if not assignments: + session.delete(ref) + + def get_object_assignments(self, policy_id, object_id=None, category_id=None): + with self.get_session_for_write() as session: + query = session.query(ObjectAssignment) + if object_id and category_id: + query = query.filter_by(policy_id=policy_id, object_id=object_id, category_id=category_id) + elif object_id: + query = query.filter_by(policy_id=policy_id, object_id=object_id) + else: + query = query.filter_by(policy_id=policy_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def add_object_assignment(self, policy_id, object_id, category_id, data_id): + with self.get_session_for_write() as session: + query = session.query(ObjectAssignment) + query = query.filter_by(policy_id=policy_id, object_id=object_id, category_id=category_id) + ref = query.first() + if ref: + old_ref = copy.deepcopy(ref.to_dict()) + assignments = old_ref["assignments"] + assignments.append(data_id) + setattr(ref, "assignments", assignments) + else: + ref = ObjectAssignment.from_dict( + { + "id": uuid4().hex, + "policy_id": policy_id, + "object_id": object_id, + "category_id": category_id, + "assignments": [data_id, ], + } + ) + session.add(ref) + return {ref.id: ref.to_dict()} + + def delete_object_assignment(self, policy_id, object_id, category_id, data_id): + with self.get_session_for_write() as session: + query = session.query(ObjectAssignment) + query = query.filter_by(policy_id=policy_id, object_id=object_id, category_id=category_id) + ref = query.first() + if ref: + old_ref = copy.deepcopy(ref.to_dict()) + assignments = old_ref["assignments"] + # TODO (asteroide): if data_id is None, delete all + if data_id in assignments: + assignments.remove(data_id) + # FIXME (asteroide): the setattr doesn't work here ; the assignments is not updated in the database + setattr(ref, "assignments", assignments) + if not assignments: + session.delete(ref) + + def get_action_assignments(self, policy_id, action_id=None, category_id=None): + with self.get_session_for_write() as session: + query = session.query(ActionAssignment) + if action_id and category_id: + query = query.filter_by(policy_id=policy_id, action_id=action_id, category_id=category_id) + elif action_id: + query = query.filter_by(policy_id=policy_id, action_id=action_id) + else: + query = query.filter_by(policy_id=policy_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def add_action_assignment(self, policy_id, action_id, category_id, data_id): + with self.get_session_for_write() as session: + query = session.query(ActionAssignment) + query = query.filter_by(policy_id=policy_id, action_id=action_id, category_id=category_id) + ref = query.first() + if ref: + old_ref = copy.deepcopy(ref.to_dict()) + assignments = old_ref["assignments"] + assignments.append(data_id) + # FIXME (asteroide): the setattr doesn't work here ; the assignments is not updated in the database + setattr(ref, "assignments", assignments) + else: + ref = ActionAssignment.from_dict( + { + "id": uuid4().hex, + "policy_id": policy_id, + "action_id": action_id, + "category_id": category_id, + "assignments": [data_id, ], + } + ) + session.add(ref) + return {ref.id: ref.to_dict()} + + def delete_action_assignment(self, policy_id, action_id, category_id, data_id): + with self.get_session_for_write() as session: + query = session.query(ActionAssignment) + query = query.filter_by(policy_id=policy_id, action_id=action_id, category_id=category_id) + ref = query.first() + if ref: + old_ref = copy.deepcopy(ref.to_dict()) + assignments = old_ref["assignments"] + # TODO (asteroide): if data_id is None, delete all + if data_id in assignments: + assignments.remove(data_id) + # FIXME (asteroide): the setattr doesn't work here ; the assignments is not updated in the database + setattr(ref, "assignments", assignments) + if not assignments: + session.delete(ref) + + def get_rules(self, policy_id, rule_id=None, meta_rule_id=None): + with self.get_session_for_read() as session: + query = session.query(Rule) + if rule_id: + query = query.filter_by(policy_id=policy_id, rule_id=rule_id) + ref = query.first() + return {ref.id: ref.to_dict()} + elif meta_rule_id: + query = query.filter_by(policy_id=policy_id, meta_rule_id=meta_rule_id) + ref_list = query.all() + return { + "meta_rule_id": meta_rule_id, + "policy_id": policy_id, + "rules": list(map(lambda x: x.to_dict(), ref_list)) + } + else: + query = query.filter_by(policy_id=policy_id) + ref_list = query.all() + return { + "policy_id": policy_id, + "rules": list(map(lambda x: x.to_dict(), ref_list)) + } + + def add_rule(self, policy_id, meta_rule_id, value): + with self.get_session_for_write() as session: + query = session.query(Rule) + query = query.filter_by(policy_id=policy_id, meta_rule_id=meta_rule_id) + ref_list = query.all() + LOG.info("add_rule {}".format(ref_list)) + LOG.info("add_rule {}".format(value)) + rules = list(map(lambda x: x.rule, ref_list)) + LOG.info("add_rule rules={}".format(rules)) + if not rules or value not in rules: + LOG.info("add_rule IN IF") + ref = Rule.from_dict( + { + "id": uuid4().hex, + "policy_id": policy_id, + "meta_rule_id": meta_rule_id, + "rule": value + } + ) + session.add(ref) + return {ref.id: ref.to_dict()} + return {} + + def delete_rule(self, policy_id, rule_id): + with self.get_session_for_write() as session: + query = session.query(Rule) + query = query.filter_by(policy_id=policy_id, id=rule_id) + ref = query.first() + if ref: + session.delete(ref) + + +class ModelConnector(BaseConnector, ModelDriver): + + def update_model(self, model_id, value): + with self.get_session_for_write() as session: + query = session.query(Model) + if model_id: + query = query.filter_by(id=model_id) + ref = query.first() + if ref: + d = dict(ref.value) + d.update(value) + setattr(ref, "value", d) + return {ref.id: ref.to_dict()} + + def delete_model(self, model_id): + with self.get_session_for_write() as session: + ref = session.query(Model).get(model_id) + session.delete(ref) + + def add_model(self, model_id=None, value=None): + with self.get_session_for_write() as session: + new = Model.from_dict({ + "id": model_id if model_id else uuid4().hex, + "value": value + }) + session.add(new) + return {new.id: new.to_dict()} + + def get_models(self, model_id=None): + with self.get_session_for_read() as session: + query = session.query(Model) + if model_id: + ref_list = query.filter(Model.id == model_id) + else: + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def set_meta_rule(self, meta_rule_id, value): + with self.get_session_for_write() as session: + query = session.query(MetaRule) + query = query.filter_by(id=meta_rule_id) + ref = query.first() + if not ref: + ref = MetaRule.from_dict( + { + "id": uuid4().hex, + "value": value + } + ) + session.add(ref) + else: + setattr(ref, "value", value) + return {ref.id: ref.to_dict()} + + def get_meta_rules(self, meta_rule_id=None): + with self.get_session_for_read() as session: + query = session.query(MetaRule) + if meta_rule_id: + query = query.filter_by(id=meta_rule_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def delete_meta_rule(self, meta_rule_id=None): + with self.get_session_for_write() as session: + query = session.query(MetaRule) + query = query.filter_by(id=meta_rule_id) + ref = query.first() + if ref: + session.delete(ref) + + def get_subject_categories(self, category_id=None): + with self.get_session_for_read() as session: + query = session.query(SubjectCategory) + if category_id: + query = query.filter_by(id=category_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def add_subject_category(self, name, description): + with self.get_session_for_write() as session: + query = session.query(SubjectCategory) + query = query.filter_by(name=name) + ref = query.first() + if not ref: + ref = SubjectCategory.from_dict( + { + "id": uuid4().hex, + "name": name, + "description": description + } + ) + session.add(ref) + return {ref.id: ref.to_dict()} + + def delete_subject_category(self, category_id): + with self.get_session_for_write() as session: + query = session.query(SubjectCategory) + query = query.filter_by(id=category_id) + ref = query.first() + if ref: + session.delete(ref) + + def get_object_categories(self, category_id=None): + with self.get_session_for_read() as session: + query = session.query(ObjectCategory) + if category_id: + query = query.filter_by(id=category_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def add_object_category(self, name, description): + with self.get_session_for_write() as session: + query = session.query(ObjectCategory) + query = query.filter_by(name=name) + ref = query.first() + if not ref: + ref = ObjectCategory.from_dict( + { + "id": uuid4().hex, + "name": name, + "description": description + } + ) + session.add(ref) + return {ref.id: ref.to_dict()} + + def delete_object_category(self, category_id): + with self.get_session_for_write() as session: + query = session.query(ObjectCategory) + query = query.filter_by(id=category_id) + ref = query.first() + if ref: + session.delete(ref) + + def get_action_categories(self, category_id=None): + with self.get_session_for_read() as session: + query = session.query(ActionCategory) + if category_id: + query = query.filter_by(id=category_id) + ref_list = query.all() + return {_ref.id: _ref.to_dict() for _ref in ref_list} + + def add_action_category(self, name, description): + with self.get_session_for_write() as session: + query = session.query(ActionCategory) + query = query.filter_by(name=name) + ref = query.first() + if not ref: + ref = ActionCategory.from_dict( + { + "id": uuid4().hex, + "name": name, + "description": description + } + ) + session.add(ref) + return {ref.id: ref.to_dict()} + + def delete_action_category(self, category_id): + with self.get_session_for_write() as session: + query = session.query(ActionCategory) + query = query.filter_by(id=category_id) + ref = query.first() + if ref: + session.delete(ref) + # Getter and Setter for subject_category + + # def get_subject_categories_dict(self, intra_extension_id): + # with self.get_session_for_read() as session: + # query = session.query(SubjectCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref_list = query.all() + # return {_ref.id: _ref.subject_category for _ref in ref_list} + # + # def set_subject_category_dict(self, intra_extension_id, subject_category_id, subject_category_dict): + # with self.get_session_for_write() as session: + # query = session.query(SubjectCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=subject_category_id) + # ref = query.first() + # new_ref = SubjectCategory.from_dict( + # { + # "id": subject_category_id, + # 'subject_category': subject_category_dict, + # 'intra_extension_id': intra_extension_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in SubjectCategory.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # # session.flush() + # return {subject_category_id: SubjectCategory.to_dict(ref)['subject_category']} + # + # def del_subject_category(self, intra_extension_id, subject_category_id): + # with self.get_session_for_write() as session: + # query = session.query(SubjectCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=subject_category_id) + # ref = query.first() + # self.del_subject_assignment(intra_extension_id, None, None, None) + # session.delete(ref) + # + # # Getter and Setter for object_category + # + # def get_object_categories_dict(self, intra_extension_id): + # with self.get_session_for_read() as session: + # query = session.query(ObjectCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref_list = query.all() + # return {_ref.id: _ref.object_category for _ref in ref_list} + # + # def set_object_category_dict(self, intra_extension_id, object_category_id, object_category_dict): + # with self.get_session_for_write() as session: + # query = session.query(ObjectCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=object_category_id) + # ref = query.first() + # new_ref = ObjectCategory.from_dict( + # { + # "id": object_category_id, + # 'object_category': object_category_dict, + # 'intra_extension_id': intra_extension_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in ObjectCategory.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {object_category_id: ObjectCategory.to_dict(ref)['object_category']} + # + # def del_object_category(self, intra_extension_id, object_category_id): + # with self.get_session_for_write() as session: + # query = session.query(ObjectCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=object_category_id) + # ref = query.first() + # self.del_object_assignment(intra_extension_id, None, None, None) + # session.delete(ref) + # + # # Getter and Setter for action_category + # + # def get_action_categories_dict(self, intra_extension_id): + # with self.get_session_for_read() as session: + # query = session.query(ActionCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref_list = query.all() + # return {_ref.id: _ref.action_category for _ref in ref_list} + # + # def set_action_category_dict(self, intra_extension_id, action_category_id, action_category_dict): + # with self.get_session_for_write() as session: + # query = session.query(ActionCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=action_category_id) + # ref = query.first() + # new_ref = ActionCategory.from_dict( + # { + # "id": action_category_id, + # 'action_category': action_category_dict, + # 'intra_extension_id': intra_extension_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in ActionCategory.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {action_category_id: ActionCategory.to_dict(ref)['action_category']} + # + # def del_action_category(self, intra_extension_id, action_category_id): + # with self.get_session_for_write() as session: + # query = session.query(ActionCategory) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=action_category_id) + # ref = query.first() + # self.del_action_assignment(intra_extension_id, None, None, None) + # session.delete(ref) + + # Perimeter + + # def get_subjects_dict(self, intra_extension_id): + # with self.get_session_for_read() as session: + # query = session.query(Subject) + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref_list = query.all() + # return {_ref.id: _ref.subject for _ref in ref_list} + # + # def set_subject_dict(self, intra_extension_id, subject_id, subject_dict): + # with self.get_session_for_write() as session: + # query = session.query(Subject) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=subject_id) + # ref = query.first() + # # if 'id' in subject_dict: + # # subject_dict['id'] = subject_id + # new_ref = Subject.from_dict( + # { + # "id": subject_id, + # 'subject': subject_dict, + # 'intra_extension_id': intra_extension_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in Subject.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {subject_id: Subject.to_dict(ref)['subject']} + # + # def del_subject(self, intra_extension_id, subject_id): + # with self.get_session_for_write() as session: + # query = session.query(Subject) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=subject_id) + # ref = query.first() + # session.delete(ref) + # + # def get_objects_dict(self, intra_extension_id): + # with self.get_session_for_read() as session: + # query = session.query(Object) + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref_list = query.all() + # return {_ref.id: _ref.object for _ref in ref_list} + # + # def set_object_dict(self, intra_extension_id, object_id, object_dict): + # with self.get_session_for_write() as session: + # query = session.query(Object) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=object_id) + # ref = query.first() + # new_ref = Object.from_dict( + # { + # "id": object_id, + # 'object': object_dict, + # 'intra_extension_id': intra_extension_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in Object.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {object_id: Object.to_dict(ref)['object']} + # + # def del_object(self, intra_extension_id, object_id): + # with self.get_session_for_write() as session: + # query = session.query(Object) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=object_id) + # ref = query.first() + # session.delete(ref) + # + # def get_actions_dict(self, intra_extension_id): + # with self.get_session_for_read() as session: + # query = session.query(Action) + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref_list = query.all() + # return {_ref.id: _ref.action for _ref in ref_list} + # + # def set_action_dict(self, intra_extension_id, action_id, action_dict): + # with self.get_session_for_write() as session: + # query = session.query(Action) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=action_id) + # ref = query.first() + # new_ref = Action.from_dict( + # { + # "id": action_id, + # 'action': action_dict, + # 'intra_extension_id': intra_extension_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in Action.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {action_id: Action.to_dict(ref)['action']} + # + # def del_action(self, intra_extension_id, action_id): + # with self.get_session_for_write() as session: + # query = session.query(Action) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=action_id) + # ref = query.first() + # session.delete(ref) + + # Getter and Setter for subject_scope + + # def get_subject_scopes_dict(self, intra_extension_id, subject_category_id): + # with self.get_session_for_read() as session: + # query = session.query(SubjectScope) + # query = query.filter_by(intra_extension_id=intra_extension_id, subject_category_id=subject_category_id) + # ref_list = query.all() + # return {_ref.id: _ref.subject_scope for _ref in ref_list} + # + # def set_subject_scope_dict(self, intra_extension_id, subject_category_id, subject_scope_id, subject_scope_dict): + # with self.get_session_for_write() as session: + # query = session.query(SubjectScope) + # query = query.filter_by(intra_extension_id=intra_extension_id, subject_category_id=subject_category_id, id=subject_scope_id) + # ref = query.first() + # new_ref = SubjectScope.from_dict( + # { + # "id": subject_scope_id, + # 'subject_scope': subject_scope_dict, + # 'intra_extension_id': intra_extension_id, + # 'subject_category_id': subject_category_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in Subject.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {subject_scope_id: SubjectScope.to_dict(ref)['subject_scope']} + # + # def del_subject_scope(self, intra_extension_id, subject_category_id, subject_scope_id): + # with self.get_session_for_write() as session: + # query = session.query(SubjectScope) + # if not subject_category_id or not subject_scope_id: + # query = query.filter_by(intra_extension_id=intra_extension_id) + # for ref in query.all(): + # session.delete(ref) + # else: + # query = query.filter_by(intra_extension_id=intra_extension_id, subject_category_id=subject_category_id, id=subject_scope_id) + # ref = query.first() + # session.delete(ref) + # + # # Getter and Setter for object_category_scope + # + # def get_object_scopes_dict(self, intra_extension_id, object_category_id): + # with self.get_session_for_read() as session: + # query = session.query(ObjectScope) + # query = query.filter_by(intra_extension_id=intra_extension_id, object_category_id=object_category_id) + # ref_list = query.all() + # return {_ref.id: _ref.object_scope for _ref in ref_list} + # + # def set_object_scope_dict(self, intra_extension_id, object_category_id, object_scope_id, object_scope_dict): + # with self.get_session_for_write() as session: + # query = session.query(ObjectScope) + # query = query.filter_by(intra_extension_id=intra_extension_id, object_category_id=object_category_id, id=object_scope_id) + # ref = query.first() + # new_ref = ObjectScope.from_dict( + # { + # "id": object_scope_id, + # 'object_scope': object_scope_dict, + # 'intra_extension_id': intra_extension_id, + # 'object_category_id': object_category_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in Object.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {object_scope_id: ObjectScope.to_dict(ref)['object_scope']} + # + # def del_object_scope(self, intra_extension_id, object_category_id, object_scope_id): + # with self.get_session_for_write() as session: + # query = session.query(ObjectScope) + # if not object_category_id or not object_scope_id: + # query = query.filter_by(intra_extension_id=intra_extension_id) + # for ref in query.all(): + # session.delete(ref) + # else: + # query = query.filter_by(intra_extension_id=intra_extension_id, object_category_id=object_category_id, id=object_scope_id) + # ref = query.first() + # session.delete(ref) + # + # # Getter and Setter for action_scope + # + # def get_action_scopes_dict(self, intra_extension_id, action_category_id): + # with self.get_session_for_read() as session: + # query = session.query(ActionScope) + # query = query.filter_by(intra_extension_id=intra_extension_id, action_category_id=action_category_id) + # ref_list = query.all() + # return {_ref.id: _ref.action_scope for _ref in ref_list} + # + # def set_action_scope_dict(self, intra_extension_id, action_category_id, action_scope_id, action_scope_dict): + # with self.get_session_for_write() as session: + # query = session.query(ActionScope) + # query = query.filter_by(intra_extension_id=intra_extension_id, action_category_id=action_category_id, id=action_scope_id) + # ref = query.first() + # new_ref = ActionScope.from_dict( + # { + # "id": action_scope_id, + # 'action_scope': action_scope_dict, + # 'intra_extension_id': intra_extension_id, + # 'action_category_id': action_category_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in Action.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {action_scope_id: ActionScope.to_dict(ref)['action_scope']} + # + # def del_action_scope(self, intra_extension_id, action_category_id, action_scope_id): + # with self.get_session_for_write() as session: + # query = session.query(ActionScope) + # if not action_category_id or not action_scope_id: + # query = query.filter_by(intra_extension_id=intra_extension_id) + # for ref in query.all(): + # session.delete(ref) + # else: + # query = query.filter_by(intra_extension_id=intra_extension_id, action_category_id=action_category_id, id=action_scope_id) + # ref = query.first() + # session.delete(ref) + # + # # Getter and Setter for subject_category_assignment + # + # def get_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id): + # with self.get_session_for_read() as session: + # query = session.query(SubjectAssignment) + # if not subject_id or not subject_category_id or not subject_category_id: + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref = query.all() + # return ref + # else: + # query = query.filter_by(intra_extension_id=intra_extension_id, subject_id=subject_id, subject_category_id=subject_category_id) + # ref = query.first() + # if not ref: + # return list() + # LOG.info("get_subject_assignment_list {}".format(ref.subject_assignment)) + # return list(ref.subject_assignment) + # + # def set_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id, subject_assignment_list=[]): + # with self.get_session_for_write() as session: + # query = session.query(SubjectAssignment) + # query = query.filter_by(intra_extension_id=intra_extension_id, subject_id=subject_id, subject_category_id=subject_category_id) + # ref = query.first() + # new_ref = SubjectAssignment.from_dict( + # { + # "id": uuid4().hex, + # 'subject_assignment': subject_assignment_list, + # 'intra_extension_id': intra_extension_id, + # 'subject_id': subject_id, + # 'subject_category_id': subject_category_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in SubjectAssignment.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return subject_assignment_list + # + # def add_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id, subject_scope_id): + # new_subject_assignment_list = self.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id) + # if subject_scope_id not in new_subject_assignment_list: + # new_subject_assignment_list.append(subject_scope_id) + # return self.set_subject_assignment_list(intra_extension_id, subject_id, subject_category_id, new_subject_assignment_list) + # + # def del_subject_assignment(self, intra_extension_id, subject_id, subject_category_id, subject_scope_id): + # if not subject_id or not subject_category_id or not subject_category_id: + # with self.get_session_for_write() as session: + # for ref in self.get_subject_assignment_list(intra_extension_id, None, None): + # session.delete(ref) + # session.flush() + # return + # new_subject_assignment_list = self.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id) + # new_subject_assignment_list.remove(subject_scope_id) + # return self.set_subject_assignment_list(intra_extension_id, subject_id, subject_category_id, new_subject_assignment_list) + # + # # Getter and Setter for object_category_assignment + # + # def get_object_assignment_list(self, intra_extension_id, object_id, object_category_id): + # with self.get_session_for_read() as session: + # query = session.query(ObjectAssignment) + # if not object_id or not object_category_id or not object_category_id: + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref = query.all() + # return ref + # else: + # query = query.filter_by(intra_extension_id=intra_extension_id, object_id=object_id, object_category_id=object_category_id) + # ref = query.first() + # if not ref: + # return list() + # return list(ref.object_assignment) + # + # def set_object_assignment_list(self, intra_extension_id, object_id, object_category_id, object_assignment_list=[]): + # with self.get_session_for_write() as session: + # query = session.query(ObjectAssignment) + # query = query.filter_by(intra_extension_id=intra_extension_id, object_id=object_id, object_category_id=object_category_id) + # ref = query.first() + # new_ref = ObjectAssignment.from_dict( + # { + # "id": uuid4().hex, + # 'object_assignment': object_assignment_list, + # 'intra_extension_id': intra_extension_id, + # 'object_id': object_id, + # 'object_category_id': object_category_id + # } + # ) + # if not ref: + # session.add(new_ref) + # else: + # for attr in ObjectAssignment.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return self.get_object_assignment_list(intra_extension_id, object_id, object_category_id) + # + # def add_object_assignment_list(self, intra_extension_id, object_id, object_category_id, object_scope_id): + # new_object_assignment_list = self.get_object_assignment_list(intra_extension_id, object_id, object_category_id) + # if object_scope_id not in new_object_assignment_list: + # new_object_assignment_list.append(object_scope_id) + # return self.set_object_assignment_list(intra_extension_id, object_id, object_category_id, new_object_assignment_list) + # + # def del_object_assignment(self, intra_extension_id, object_id, object_category_id, object_scope_id): + # if not object_id or not object_category_id or not object_category_id: + # with self.get_session_for_write() as session: + # for ref in self.get_object_assignment_list(intra_extension_id, None, None): + # session.delete(ref) + # session.flush() + # return + # new_object_assignment_list = self.get_object_assignment_list(intra_extension_id, object_id, object_category_id) + # new_object_assignment_list.remove(object_scope_id) + # return self.set_object_assignment_list(intra_extension_id, object_id, object_category_id, new_object_assignment_list) + # + # # Getter and Setter for action_category_assignment + # + # def get_action_assignment_list(self, intra_extension_id, action_id, action_category_id): + # with self.get_session_for_read() as session: + # query = session.query(ActionAssignment) + # if not action_id or not action_category_id or not action_category_id: + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref = query.all() + # return ref + # else: + # query = query.filter_by(intra_extension_id=intra_extension_id, action_id=action_id, action_category_id=action_category_id) + # ref = query.first() + # if not ref: + # return list() + # return list(ref.action_assignment) + # + # def set_action_assignment_list(self, intra_extension_id, action_id, action_category_id, action_assignment_list=[]): + # with self.get_session_for_write() as session: + # query = session.query(ActionAssignment) + # query = query.filter_by(intra_extension_id=intra_extension_id, action_id=action_id, action_category_id=action_category_id) + # ref = query.first() + # new_ref = ActionAssignment.from_dict( + # { + # "id": uuid4().hex, + # 'action_assignment': action_assignment_list, + # 'intra_extension_id': intra_extension_id, + # 'action_id': action_id, + # 'action_category_id': action_category_id + # } + # ) + # if not ref: + # session.add(new_ref) + # else: + # for attr in ActionAssignment.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return self.get_action_assignment_list(intra_extension_id, action_id, action_category_id) + # + # def add_action_assignment_list(self, intra_extension_id, action_id, action_category_id, action_scope_id): + # new_action_assignment_list = self.get_action_assignment_list(intra_extension_id, action_id, action_category_id) + # if action_scope_id not in new_action_assignment_list: + # new_action_assignment_list.append(action_scope_id) + # return self.set_action_assignment_list(intra_extension_id, action_id, action_category_id, new_action_assignment_list) + # + # def del_action_assignment(self, intra_extension_id, action_id, action_category_id, action_scope_id): + # if not action_id or not action_category_id or not action_category_id: + # with self.get_session_for_write() as session: + # for ref in self.get_action_assignment_list(intra_extension_id, None, None): + # session.delete(ref) + # session.flush() + # return + # new_action_assignment_list = self.get_action_assignment_list(intra_extension_id, action_id, action_category_id) + # new_action_assignment_list.remove(action_scope_id) + # return self.set_action_assignment_list(intra_extension_id, action_id, action_category_id, new_action_assignment_list) + # + # # Getter and Setter for sub_meta_rule + # + # def get_aggregation_algorithm_id(self, intra_extension_id): + # with self.get_session_for_read() as session: + # query = session.query(IntraExtension) + # query = query.filter_by(id=intra_extension_id) + # ref = query.first() + # try: + # return {"aggregation_algorithm": ref.intra_extension["aggregation_algorithm"]} + # except KeyError: + # return "" + # + # def set_aggregation_algorithm_id(self, intra_extension_id, aggregation_algorithm_id): + # with self.get_session_for_write() as session: + # query = session.query(IntraExtension) + # query = query.filter_by(id=intra_extension_id) + # ref = query.first() + # intra_extension_dict = dict(ref.intra_extension) + # intra_extension_dict["aggregation_algorithm"] = aggregation_algorithm_id + # setattr(ref, "intra_extension", intra_extension_dict) + # # session.flush() + # return {"aggregation_algorithm": ref.intra_extension["aggregation_algorithm"]} + # + # def del_aggregation_algorithm(self, intra_extension_id): + # with self.get_session_for_write() as session: + # query = session.query(IntraExtension) + # query = query.filter_by(id=intra_extension_id) + # ref = query.first() + # intra_extension_dict = dict(ref.intra_extension) + # intra_extension_dict["aggregation_algorithm"] = "" + # setattr(ref, "intra_extension", intra_extension_dict) + # return self.get_aggregation_algorithm_id(intra_extension_id) + # + # # Getter and Setter for sub_meta_rule + # + # def get_sub_meta_rules_dict(self, intra_extension_id): + # with self.get_session_for_read() as session: + # query = session.query(SubMetaRule) + # query = query.filter_by(intra_extension_id=intra_extension_id) + # ref_list = query.all() + # return {_ref.id: _ref.sub_meta_rule for _ref in ref_list} + # + # def set_sub_meta_rule_dict(self, intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict): + # with self.get_session_for_write() as session: + # query = session.query(SubMetaRule) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=sub_meta_rule_id) + # ref = query.first() + # new_ref = SubMetaRule.from_dict( + # { + # "id": sub_meta_rule_id, + # 'sub_meta_rule': sub_meta_rule_dict, + # 'intra_extension_id': intra_extension_id + # } + # ) + # if not ref: + # session.add(new_ref) + # else: + # _sub_meta_rule_dict = dict(ref.sub_meta_rule) + # _sub_meta_rule_dict.update(sub_meta_rule_dict) + # setattr(new_ref, "sub_meta_rule", _sub_meta_rule_dict) + # for attr in SubMetaRule.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return self.get_sub_meta_rules_dict(intra_extension_id) + # + # def del_sub_meta_rule(self, intra_extension_id, sub_meta_rule_id): + # with self.get_session_for_write() as session: + # query = session.query(SubMetaRule) + # query = query.filter_by(intra_extension_id=intra_extension_id, id=sub_meta_rule_id) + # ref = query.first() + # session.delete(ref) + # + # # Getter and Setter for rules + # + # def get_rules_dict(self, intra_extension_id, sub_meta_rule_id): + # with self.get_session_for_read() as session: + # query = session.query(Rule) + # query = query.filter_by(intra_extension_id=intra_extension_id, sub_meta_rule_id=sub_meta_rule_id) + # ref_list = query.all() + # return {_ref.id: _ref.rule for _ref in ref_list} + # + # def set_rule_dict(self, intra_extension_id, sub_meta_rule_id, rule_id, rule_list): + # with self.get_session_for_write() as session: + # query = session.query(Rule) + # query = query.filter_by(intra_extension_id=intra_extension_id, sub_meta_rule_id=sub_meta_rule_id, id=rule_id) + # ref = query.first() + # new_ref = Rule.from_dict( + # { + # "id": rule_id, + # 'rule': rule_list, + # 'intra_extension_id': intra_extension_id, + # 'sub_meta_rule_id': sub_meta_rule_id + # } + # ) + # if not ref: + # session.add(new_ref) + # ref = new_ref + # else: + # for attr in Rule.attributes: + # if attr != 'id': + # setattr(ref, attr, getattr(new_ref, attr)) + # # session.flush() + # return {rule_id: ref.rule} + # + # def del_rule(self, intra_extension_id, sub_meta_rule_id, rule_id): + # with self.get_session_for_write() as session: + # query = session.query(Rule) + # query = query.filter_by(intra_extension_id=intra_extension_id, sub_meta_rule_id=sub_meta_rule_id, id=rule_id) + # ref = query.first() + # session.delete(ref) + + +class SQLConnector(PDPConnector, PolicyConnector, ModelConnector): + pass + +# class InterExtension(Base): +# __tablename__ = 'inter_extension' +# attributes = [ +# 'id', +# 'requesting_intra_extension_id', +# 'requested_intra_extension_id', +# 'virtual_entity_uuid', +# 'genre', +# 'description', +# ] +# id = sql.Column(sql.String(64), primary_key=True) +# requesting_intra_extension_id = sql.Column(sql.String(64)) +# requested_intra_extension_id = sql.Column(sql.String(64)) +# virtual_entity_uuid = sql.Column(sql.String(64)) +# genre = sql.Column(sql.String(64)) +# description = sql.Column(sql.Text()) +# +# @classmethod +# def from_dict(cls, d): +# """Override parent from_dict() method with a simpler implementation. +# """ +# new_d = d.copy() +# return cls(**new_d) +# +# def to_dict(self): +# """Override parent to_dict() method with a simpler implementation. +# """ +# return dict(six.iteritems(self)) +# +# +# class InterExtensionBaseConnector(InterExtensionDriver): +# +# def get_inter_extensions(self): +# with self.get_session_for_read() as session: +# query = session.query(InterExtension.id) +# interextensions = query.all() +# return [interextension.id for interextension in interextensions] +# +# def create_inter_extensions(self, inter_id, inter_extension): +# with self.get_session_for_read() as session: +# ie_ref = InterExtension.from_dict(inter_extension) +# session.add(ie_ref) +# return InterExtension.to_dict(ie_ref) +# +# def get_inter_extension(self, uuid): +# with self.get_session_for_read() as session: +# query = session.query(InterExtension) +# query = query.filter_by(id=uuid) +# ref = query.first() +# if not ref: +# raise exception.NotFound +# return ref.to_dict() +# +# def delete_inter_extensions(self, inter_extension_id): +# with self.get_session_for_read() as session: +# ref = session.query(InterExtension).get(inter_extension_id) +# session.delete(ref) diff --git a/moonv4/moon_db/moon_db/core.py b/moonv4/moon_db/moon_db/core.py new file mode 100644 index 00000000..09c87e0b --- /dev/null +++ b/moonv4/moon_db/moon_db/core.py @@ -0,0 +1,303 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from moon_db.exception import * +from oslo_log import log as logging +from oslo_config import cfg +from stevedore.driver import DriverManager +from moon_utilities import options # noqa +from moon_db.api import model, policy, pdp, tenants, keystone + +CONF = cfg.CONF +LOG = logging.getLogger(__name__) + + +class Driver(DriverManager): + + def __init__(self, driver_name, engine_name): + LOG.info("initialization of Driver {}".format(driver_name)) + super(Driver, self).__init__( + namespace='moon_db.driver', + name=driver_name, + invoke_on_load=True, + invoke_args=(engine_name, ), + ) + + +class ModelDriver(Driver): + + def __init__(self, driver_name, engine_name): + super(ModelDriver, self).__init__(driver_name, engine_name) + + def update_model(self, model_id, value): + raise NotImplementedError() # pragma: no cover + + def delete_model(self, model_id): + raise NotImplementedError() # pragma: no cover + + def add_model(self, model_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def get_models(self, model_id=None): + raise NotImplementedError() # pragma: no cover + + def set_meta_rule(self, meta_rule_id, value): + raise NotImplementedError() # pragma: no cover + + def get_meta_rules(self, meta_rule_id=None): + raise NotImplementedError() # pragma: no cover + + def delete_meta_rule(self, meta_rule_id=None): + raise NotImplementedError() # pragma: no cover + + def get_subject_categories(self, category_id=None): + raise NotImplementedError() # pragma: no cover + + def add_subject_category(self, name, description): + raise NotImplementedError() # pragma: no cover + + def delete_subject_category(self, category_id): + raise NotImplementedError() # pragma: no cover + + def get_object_categories(self, category_id): + raise NotImplementedError() # pragma: no cover + + def add_object_category(self, category_id, value): + raise NotImplementedError() # pragma: no cover + + def delete_object_category(self, category_id): + raise NotImplementedError() # pragma: no cover + + def get_action_categories(self, category_id): + raise NotImplementedError() # pragma: no cover + + def add_action_category(self, category_id, value): + raise NotImplementedError() # pragma: no cover + + def delete_action_category(self, category_id): + raise NotImplementedError() # pragma: no cover + + +class PolicyDriver(Driver): + + def __init__(self, driver_name, engine_name): + super(PolicyDriver, self).__init__(driver_name, engine_name) + + def update_policy(self, policy_id, value): + raise NotImplementedError() # pragma: no cover + + def delete_policy(self, policy_id): + raise NotImplementedError() # pragma: no cover + + def add_policy(self, policy_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def get_policies(self, policy_id=None): + raise NotImplementedError() # pragma: no cover + + def get_subjects(self, policy_id, perimeter_id=None): + raise NotImplementedError() # pragma: no cover + + def set_subject(self, policy_id, perimeter_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def delete_subject(self, policy_id, perimeter_id): + raise NotImplementedError() # pragma: no cover + + def get_objects(self, policy_id, perimeter_id=None): + raise NotImplementedError() # pragma: no cover + + def set_object(self, policy_id, perimeter_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def delete_object(self, policy_id, perimeter_id): + raise NotImplementedError() # pragma: no cover + + def get_actions(self, policy_id, perimeter_id=None): + raise NotImplementedError() # pragma: no cover + + def set_action(self, policy_id, perimeter_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def delete_action(self, policy_id, perimeter_id): + raise NotImplementedError() # pragma: no cover + + def get_subject_data(self, policy_id, data_id=None, category_id=None): + raise NotImplementedError() # pragma: no cover + + def set_subject_data(self, policy_id, data_id=None, category_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def delete_subject_data(self, policy_id, data_id): + raise NotImplementedError() # pragma: no cover + + def get_object_data(self, policy_id, data_id=None, category_id=None): + raise NotImplementedError() # pragma: no cover + + def set_object_data(self, policy_id, data_id=None, category_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def delete_object_data(self, policy_id, data_id): + raise NotImplementedError() # pragma: no cover + + def get_action_data(self, policy_id, data_id=None, category_id=None): + raise NotImplementedError() # pragma: no cover + + def set_action_data(self, policy_id, data_id=None, category_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def delete_action_data(self, policy_id, data_id): + raise NotImplementedError() # pragma: no cover + + def get_subject_assignments(self, policy_id, subject_id=None, category_id=None): + raise NotImplementedError() # pragma: no cover + + def add_subject_assignment(self, policy_id, subject_id, category_id, data_id): + raise NotImplementedError() # pragma: no cover + + def delete_subject_assignment(self, policy_id, subject_id, category_id, data_id): + raise NotImplementedError() # pragma: no cover + + def get_object_assignments(self, policy_id, assignment_id=None): + raise NotImplementedError() # pragma: no cover + + def add_object_assignment(self, policy_id, subject_id, category_id, data_id): + raise NotImplementedError() # pragma: no cover + + def delete_object_assignment(self, policy_id, object_id, category_id, data_id): + raise NotImplementedError() # pragma: no cover + + def get_action_assignments(self, policy_id, assignment_id=None): + raise NotImplementedError() # pragma: no cover + + def add_action_assignment(self, policy_id, action_id, category_id, data_id): + raise NotImplementedError() # pragma: no cover + + def delete_action_assignment(self, policy_id, action_id, category_id, data_id): + raise NotImplementedError() # pragma: no cover + + def get_rules(self, policy_id, rule_id=None, meta_rule_id=None): + raise NotImplementedError() # pragma: no cover + + def add_rule(self, policy_id, meta_rule_id, value): + raise NotImplementedError() # pragma: no cover + + def delete_rule(self, policy_id, rule_id): + raise NotImplementedError() # pragma: no cover + + +class PDPDriver(Driver): + + def __init__(self, driver_name, engine_name): + super(PDPDriver, self).__init__(driver_name, engine_name) + + def update_pdp(self, pdp_id, value): + raise NotImplementedError() # pragma: no cover + + def delete_pdp(self, pdp_id): + raise NotImplementedError() # pragma: no cover + + def add_pdp(self, pdp_id=None, value=None): + raise NotImplementedError() # pragma: no cover + + def get_pdp(self, pdp_id=None): + raise NotImplementedError() # pragma: no cover + + +class KeystoneDriver(Driver): + + def __init__(self, driver_name, engine_name): + super(KeystoneDriver, self).__init__(driver_name, engine_name) + + +# TODO (asteroide): we may use an other driver like the SQL driver +# so we can change the driver to directly interrogate the Keystone database. +KeystoneManager = keystone.KeystoneManager( + KeystoneDriver(CONF.database.driver, CONF.database.url) +) + +# ConfigurationManager = configuration.ConfigurationManager( +# ConfigurationDriver(CONF.database_configuration.driver, CONF.database_configuration.url) +# ) + +ModelManager = model.ModelManager( + ModelDriver(CONF.database.driver, CONF.database.url) +) + +PolicyManager = policy.PolicyManager( + PolicyDriver(CONF.database.driver, CONF.database.url) +) + +PDPManager = pdp.PDPManager( + PDPDriver(CONF.database.driver, CONF.database.url) +) + + +# class LogDriver(object): +# +# def authz(self, message): +# """Log authorization message +# +# :param message: the message to log +# :type message: string +# :return: None +# """ +# raise NotImplementedError() # pragma: no cover +# +# def debug(self, message): +# """Log debug message +# +# :param message: the message to log +# :type message: string +# :return: None +# """ +# raise NotImplementedError() # pragma: no cover +# +# def info(self, message): +# """Log informational message +# +# :param message: the message to log +# :type message: string +# :return: None +# """ +# raise NotImplementedError() # pragma: no cover +# +# def warning(self, message): +# """Log warning message +# +# :param message: the message to log +# :type message: string +# :return: None +# """ +# raise NotImplementedError() # pragma: no cover +# +# def error(self, message): +# """Log error message +# +# :param message: the message to log +# :type message: string +# :return: None +# """ +# raise NotImplementedError() # pragma: no cover +# +# def critical(self, message): +# """Log critical message +# +# :param message: the message to log +# :type message: string +# :return: None +# """ +# raise NotImplementedError() # pragma: no cover +# +# def get_logs(self, options): +# """Get logs +# +# :param options: options to filter log events +# :type options: string eg: "event_number=10,from=2014-01-01-10:10:10,to=2014-01-01-12:10:10,filter=expression" +# :return: a list of log events +# +# TIME_FORMAT is '%Y-%m-%d-%H:%M:%S' +# """ +# raise NotImplementedError() # pragma: no cover diff --git a/moonv4/moon_db/moon_db/db_manager.py b/moonv4/moon_db/moon_db/db_manager.py new file mode 100644 index 00000000..1b0034ee --- /dev/null +++ b/moonv4/moon_db/moon_db/db_manager.py @@ -0,0 +1,47 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. +""" +""" + +import os +import sys +import glob +import argparse +import importlib +from oslo_config import cfg +from oslo_log import log as logging +from sqlalchemy import create_engine +from moon_db.migrate_repo import versions + +# Note (dthom): The next line must be called before the next import +# aka before registering all the options +cfg.CONF.register_cli_opt(cfg.StrOpt('command', positional=True, + help="The command to execute (upgrade, downgrade)")) +from moon_utilities import options # noqa + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + +engine = create_engine(CONF.database.url) + + +def format_data(ext): + return ext.name, ext.obj.upgrade() + + +def run(): + files = glob.glob(versions.__path__[0] + "/[0-9][0-9][0-9]*.py") + # args = set_options() + for filename in files: + filename = os.path.basename(filename).replace(".py", "") + o = importlib.import_module("moon_db.migrate_repo.versions.{}".format(filename)) + LOG.info("Command is {}".format(CONF.command)) + if CONF.command in ("upgrade", "u", "up"): + LOG.info("upgrading moon_db.migrate_repo.versions.{}".format(filename)) + o.upgrade(engine) + elif CONF.command in ("downgrade", "d", "down"): + LOG.info("downgrading moon_db.migrate_repo.versions.{}".format(filename)) + o.downgrade(engine) + LOG.info("Done!") diff --git a/moonv4/moon_db/moon_db/exception.py b/moonv4/moon_db/moon_db/exception.py new file mode 100644 index 00000000..21b6dd62 --- /dev/null +++ b/moonv4/moon_db/moon_db/exception.py @@ -0,0 +1,410 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +# from keystone.common import dependency +# from keystone.exception import Error +# from keystone.i18n import _, _LW +import logging +# from oslo_log import log +import logging + +LOG = logging.getLogger(__name__) +_ = str + + +class Error(Exception): + pass + + +class MoonErrorMetaClass(type): + + def __init__(cls, name, bases, dct): + super(MoonErrorMetaClass, cls).__init__(name, bases, dct) + cls.hierarchy += "/"+str(name) + + +class MoonError(Error): + __metaclass__ = MoonErrorMetaClass + hierarchy = "" + message_format = _("There is an error requesting the Moon platform.") + code = 400 + title = 'Moon Error' + logger = "ERROR" + + def __init__(self, message=""): + if message: + self.message_format = message + super(MoonError, self).__init__() + + def __del__(self): + message = "{} ({})".format(self.hierarchy, self.message_format) + if self.logger == "ERROR": + LOG.error(message) + elif self.logger == "WARNING": + LOG.warning(message) + elif self.logger == "CRITICAL": + LOG.critical(message) + elif self.logger == "AUTHZ": + LOG.error(message) + else: + LOG.info(message) + + +# Exceptions for Tenant + +class TenantException(MoonError): + message_format = _("There is an error requesting this tenant.") + code = 400 + title = 'Tenant Error' + logger = "ERROR" + + +class TenantUnknown(TenantException): + message_format = _("The tenant is unknown.") + code = 400 + title = 'Tenant Unknown' + logger = "ERROR" + + +class TenantAddedNameExisting(TenantException): + message_format = _("The tenant name is existing.") + code = 400 + title = 'Added Tenant Name Existing' + logger = "ERROR" + + +class TenantNoIntraExtension(TenantException): + message_format = _("The tenant has not intra_extension.") + code = 400 + title = 'Tenant No Intra_Extension' + logger = "ERROR" + + +class TenantNoIntraAuthzExtension(TenantNoIntraExtension): + message_format = _("The tenant has not intra_admin_extension.") + code = 400 + title = 'Tenant No Intra_Admin_Extension' + logger = "ERROR" + +# Exceptions for IntraExtension + + +class IntraExtensionException(MoonError): + message_format = _("There is an error requesting this IntraExtension.") + code = 400 + title = 'Extension Error' + + +class IntraExtensionUnknown(IntraExtensionException): + message_format = _("The intra_extension is unknown.") + code = 400 + title = 'Intra Extension Unknown' + logger = "Error" + + +class RootExtensionUnknown(IntraExtensionUnknown): + message_format = _("The root_extension is unknown.") + code = 400 + title = 'Root Extension Unknown' + logger = "Error" + + +class RootExtensionNotInitialized(IntraExtensionException): + message_format = _("The root_extension is not initialized.") + code = 400 + title = 'Root Extension Not Initialized' + logger = "Error" + + +class IntraExtensionCreationError(IntraExtensionException): + message_format = _("The arguments for the creation of this Extension were malformed.") + code = 400 + title = 'Intra Extension Creation Error' + + +# Authz exceptions + +class AuthzException(MoonError): + message_format = _("There is an authorization error requesting this IntraExtension.") + code = 403 + title = 'Authz Exception' + logger = "AUTHZ" + + +# Admin exceptions + +class AdminException(MoonError): + message_format = _("There is an error requesting this Authz IntraExtension.") + code = 400 + title = 'Authz Exception' + logger = "AUTHZ" + + +class AdminMetaData(AdminException): + code = 400 + title = 'Metadata Exception' + + +class AdminPerimeter(AdminException): + code = 400 + title = 'Perimeter Exception' + + +class AdminScope(AdminException): + code = 400 + title = 'Scope Exception' + + +class AdminAssignment(AdminException): + code = 400 + title = 'Assignment Exception' + + +class AdminMetaRule(AdminException): + code = 400 + title = 'Aggregation Algorithm Exception' + + +class AdminRule(AdminException): + code = 400 + title = 'Rule Exception' + + +class SubjectCategoryNameExisting(AdminMetaData): + message_format = _("The given subject category name is existing.") + code = 400 + title = 'Subject Category Name Existing' + logger = "ERROR" + + +class ObjectCategoryNameExisting(AdminMetaData): + message_format = _("The given object category name is existing.") + code = 400 + title = 'Object Category Name Existing' + logger = "ERROR" + + +class ActionCategoryNameExisting(AdminMetaData): + message_format = _("The given action category name is existing.") + code = 400 + title = 'Action Category Name Existing' + logger = "ERROR" + + +class SubjectCategoryUnknown(AdminMetaData): + message_format = _("The given subject category is unknown.") + code = 400 + title = 'Subject Category Unknown' + logger = "ERROR" + + +class ObjectCategoryUnknown(AdminMetaData): + message_format = _("The given object category is unknown.") + code = 400 + title = 'Object Category Unknown' + logger = "ERROR" + + +class ActionCategoryUnknown(AdminMetaData): + message_format = _("The given action category is unknown.") + code = 400 + title = 'Action Category Unknown' + logger = "ERROR" + + +class SubjectUnknown(AdminPerimeter): + message_format = _("The given subject is unknown.") + code = 400 + title = 'Subject Unknown' + logger = "ERROR" + + +class ObjectUnknown(AdminPerimeter): + message_format = _("The given object is unknown.") + code = 400 + title = 'Object Unknown' + logger = "ERROR" + + +class ActionUnknown(AdminPerimeter): + message_format = _("The given action is unknown.") + code = 400 + title = 'Action Unknown' + logger = "ERROR" + + +class SubjectNameExisting(AdminPerimeter): + message_format = _("The given subject name is existing.") + code = 400 + title = 'Subject Name Existing' + logger = "ERROR" + + +class ObjectNameExisting(AdminPerimeter): + message_format = _("The given object name is existing.") + code = 400 + title = 'Object Name Existing' + logger = "ERROR" + + +class ActionNameExisting(AdminPerimeter): + message_format = _("The given action name is existing.") + code = 400 + title = 'Action Name Existing' + logger = "ERROR" + + +class ObjectsWriteNoAuthorized(AdminPerimeter): + message_format = _("The modification on Objects is not authorized.") + code = 400 + title = 'Objects Write No Authorized' + logger = "AUTHZ" + + +class ActionsWriteNoAuthorized(AdminPerimeter): + message_format = _("The modification on Actions is not authorized.") + code = 400 + title = 'Actions Write No Authorized' + logger = "AUTHZ" + + +class SubjectScopeUnknown(AdminScope): + message_format = _("The given subject scope is unknown.") + code = 400 + title = 'Subject Scope Unknown' + logger = "ERROR" + + +class ObjectScopeUnknown(AdminScope): + message_format = _("The given object scope is unknown.") + code = 400 + title = 'Object Scope Unknown' + logger = "ERROR" + + +class ActionScopeUnknown(AdminScope): + message_format = _("The given action scope is unknown.") + code = 400 + title = 'Action Scope Unknown' + logger = "ERROR" + + +class SubjectScopeNameExisting(AdminScope): + message_format = _("The given subject scope name is existing.") + code = 400 + title = 'Subject Scope Name Existing' + logger = "ERROR" + + +class ObjectScopeNameExisting(AdminScope): + message_format = _("The given object scope name is existing.") + code = 400 + title = 'Object Scope Name Existing' + logger = "ERROR" + + +class ActionScopeNameExisting(AdminScope): + message_format = _("The given action scope name is existing.") + code = 400 + title = 'Action Scope Name Existing' + logger = "ERROR" + + +class SubjectAssignmentUnknown(AdminAssignment): + message_format = _("The given subject assignment value is unknown.") + code = 400 + title = 'Subject Assignment Unknown' + logger = "ERROR" + + +class ObjectAssignmentUnknown(AdminAssignment): + message_format = _("The given object assignment value is unknown.") + code = 400 + title = 'Object Assignment Unknown' + logger = "ERROR" + + +class ActionAssignmentUnknown(AdminAssignment): + message_format = _("The given action assignment value is unknown.") + code = 400 + title = 'Action Assignment Unknown' + logger = "ERROR" + + +class SubjectAssignmentExisting(AdminAssignment): + message_format = _("The given subject assignment value is existing.") + code = 400 + title = 'Subject Assignment Existing' + logger = "ERROR" + + +class ObjectAssignmentExisting(AdminAssignment): + message_format = _("The given object assignment value is existing.") + code = 400 + title = 'Object Assignment Existing' + logger = "ERROR" + + +class ActionAssignmentExisting(AdminAssignment): + message_format = _("The given action assignment value is existing.") + code = 400 + title = 'Action Assignment Existing' + logger = "ERROR" + + +class AggregationAlgorithmNotExisting(AdminMetaRule): + message_format = _("The given aggregation algorithm is not existing.") + code = 400 + title = 'Aggregation Algorithm Not Existing' + logger = "ERROR" + + +class AggregationAlgorithmUnknown(AdminMetaRule): + message_format = _("The given aggregation algorithm is unknown.") + code = 400 + title = 'Aggregation Algorithm Unknown' + logger = "ERROR" + + +class SubMetaRuleAlgorithmNotExisting(AdminMetaRule): + message_format = _("The given sub_meta_rule algorithm is unknown.") + code = 400 + title = 'Sub_meta_rule Algorithm Unknown' + logger = "ERROR" + + +class SubMetaRuleUnknown(AdminMetaRule): + message_format = _("The given sub meta rule is unknown.") + code = 400 + title = 'Sub Meta Rule Unknown' + logger = "ERROR" + + +class SubMetaRuleNameExisting(AdminMetaRule): + message_format = _("The sub meta rule name already exists.") + code = 400 + title = 'Sub Meta Rule Name Existing' + logger = "ERROR" + + +class SubMetaRuleExisting(AdminMetaRule): + message_format = _("The sub meta rule already exists.") + code = 400 + title = 'Sub Meta Rule Existing' + logger = "ERROR" + + +class RuleExisting(AdminRule): + message_format = _("The rule already exists.") + code = 400 + title = 'Rule Existing' + logger = "ERROR" + + +class RuleUnknown(AdminRule): + message_format = _("The rule for that request doesn't exist.") + code = 400 + title = 'Rule Unknown' + logger = "ERROR" diff --git a/moonv4/moon_db/moon_db/migrate_repo/__init__.py b/moonv4/moon_db/moon_db/migrate_repo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/moonv4/moon_db/moon_db/migrate_repo/versions/001_moon.py b/moonv4/moon_db/moon_db/migrate_repo/versions/001_moon.py new file mode 100644 index 00000000..73170ef0 --- /dev/null +++ b/moonv4/moon_db/moon_db/migrate_repo/versions/001_moon.py @@ -0,0 +1,216 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import sqlalchemy as sql + + +def upgrade(migrate_engine): + meta = sql.MetaData() + meta.bind = migrate_engine + + table = sql.Table( + 'pdp', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + table.create(migrate_engine, checkfirst=True) + + table = sql.Table( + 'policies', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + table.create(migrate_engine, checkfirst=True) + + table = sql.Table( + 'models', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + table.create(migrate_engine, checkfirst=True) + + subject_categories_table = sql.Table( + 'subject_categories', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('name', sql.String(256), nullable=False), + sql.Column('description', sql.String(256), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + subject_categories_table.create(migrate_engine, checkfirst=True) + + object_categories_table = sql.Table( + 'object_categories', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('name', sql.String(256), nullable=False), + sql.Column('description', sql.String(256), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + object_categories_table.create(migrate_engine, checkfirst=True) + + action_categories_table = sql.Table( + 'action_categories', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('name', sql.String(256), nullable=False), + sql.Column('description', sql.String(256), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + action_categories_table.create(migrate_engine, checkfirst=True) + + subjects_table = sql.Table( + 'subjects', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + subjects_table.create(migrate_engine, checkfirst=True) + + objects_table = sql.Table( + 'objects', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + objects_table.create(migrate_engine, checkfirst=True) + + actions_table = sql.Table( + 'actions', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + actions_table.create(migrate_engine, checkfirst=True) + + subject_data_table = sql.Table( + 'subject_data', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + sql.Column('category_id', sql.ForeignKey("subject_categories.id"), nullable=False), + sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), + mysql_engine='InnoDB', + mysql_charset='utf8') + subject_data_table.create(migrate_engine, checkfirst=True) + + object_data_table = sql.Table( + 'object_data', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + sql.Column('category_id', sql.ForeignKey("object_categories.id"), nullable=False), + sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), + mysql_engine='InnoDB', + mysql_charset='utf8') + object_data_table.create(migrate_engine, checkfirst=True) + + action_data_table = sql.Table( + 'action_data', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + sql.Column('category_id', sql.ForeignKey("action_categories.id"), nullable=False), + sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), + mysql_engine='InnoDB', + mysql_charset='utf8') + action_data_table.create(migrate_engine, checkfirst=True) + + subject_assignments_table = sql.Table( + 'subject_assignments', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('assignments', sql.Text(), nullable=True), + sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), + sql.Column('subject_id', sql.ForeignKey("subjects.id"), nullable=False), + sql.Column('category_id', sql.ForeignKey("subject_categories.id"), nullable=False), + mysql_engine='InnoDB', + mysql_charset='utf8') + subject_assignments_table.create(migrate_engine, checkfirst=True) + + object_assignments_table = sql.Table( + 'object_assignments', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('assignments', sql.Text(), nullable=True), + sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), + sql.Column('object_id', sql.ForeignKey("objects.id"), nullable=False), + sql.Column('category_id', sql.ForeignKey("object_categories.id"), nullable=False), + mysql_engine='InnoDB', + mysql_charset='utf8') + object_assignments_table.create(migrate_engine, checkfirst=True) + + action_assignments_table = sql.Table( + 'action_assignments', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('assignments', sql.Text(), nullable=True), + sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), + sql.Column('action_id', sql.ForeignKey("actions.id"), nullable=False), + sql.Column('category_id', sql.ForeignKey("action_categories.id"), nullable=False), + mysql_engine='InnoDB', + mysql_charset='utf8') + action_assignments_table.create(migrate_engine, checkfirst=True) + + meta_rules_table = sql.Table( + 'meta_rules', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('value', sql.Text(), nullable=True), + mysql_engine='InnoDB', + mysql_charset='utf8') + meta_rules_table.create(migrate_engine, checkfirst=True) + + rules_table = sql.Table( + 'rules', + meta, + sql.Column('id', sql.String(64), primary_key=True), + sql.Column('rule', sql.Text(), nullable=True), + sql.Column('policy_id', sql.ForeignKey("policies.id"), nullable=False), + sql.Column('meta_rule_id', sql.ForeignKey("meta_rules.id"), nullable=False), + mysql_engine='InnoDB', + mysql_charset='utf8') + rules_table.create(migrate_engine, checkfirst=True) + + +def downgrade(migrate_engine): + meta = sql.MetaData() + meta.bind = migrate_engine + + for _table in ( + 'rules', + 'meta_rules', + 'action_assignments', + 'object_assignments', + 'subject_assignments', + 'action_data', + 'object_data', + 'subject_data', + 'actions', + 'objects', + 'subjects', + 'action_categories', + 'object_categories', + 'subject_categories', + 'models', + 'policies', + 'pdp' + ): + try: + table = sql.Table(_table, meta, autoload=True) + table.drop(migrate_engine, checkfirst=True) + except Exception as e: + print(e.message) + + diff --git a/moonv4/moon_db/moon_db/migrate_repo/versions/__init__.py b/moonv4/moon_db/moon_db/migrate_repo/versions/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/moonv4/moon_db/requirements.txt b/moonv4/moon_db/requirements.txt new file mode 100644 index 00000000..aa15e35d --- /dev/null +++ b/moonv4/moon_db/requirements.txt @@ -0,0 +1,5 @@ +stevedore +sqlalchemy +pymysql +requests +oslo.log diff --git a/moonv4/moon_db/setup.py b/moonv4/moon_db/setup.py new file mode 100644 index 00000000..51bb4539 --- /dev/null +++ b/moonv4/moon_db/setup.py @@ -0,0 +1,53 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from setuptools import setup, find_packages +import moon_db + + +setup( + + name='moon_db', + + version=moon_db.__version__, + + packages=find_packages(), + + author="Thomas Duval", + + author_email="thomas.duval@orange.com", + + description="This library is a helper to interact with the Moon database.", + + long_description=open('README.rst').read(), + + # install_requires= , + + include_package_data=True, + + url='https://git.opnfv.org/cgit/moon/', + + classifiers=[ + "Programming Language :: Python", + "Development Status :: 1 - Planning", + "License :: OSI Approved", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + ], + + entry_points={ + "moon_db.driver": + [ + "sql = moon_db.backends.sql:SQLConnector", + "flat = moon_db.backends.flat:LogConnector", + "memory = moon_db.backends.memory:ConfigurationConnector", + ], + 'console_scripts': [ + 'moon_db_manager = moon_db.db_manager:run', + ], + } + +) diff --git a/moonv4/moon_db/tests/configure_db.sh b/moonv4/moon_db/tests/configure_db.sh new file mode 100644 index 00000000..bdc259fe --- /dev/null +++ b/moonv4/moon_db/tests/configure_db.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +apt-get install mysql-server python-mysqldb python-pymysql + +mysql -uroot -ppassword <.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:focus,a:hover{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}cite{font-style:normal}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.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}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}blockquote:after,blockquote:before{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.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 col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#777;opacity:1}.form-control:-ms-input-placeholder{color:#777}.form-control::-webkit-input-placeholder{color:#777}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{line-height:34px}input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;min-height:20px;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.form-horizontal .form-group-sm .form-control,.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-horizontal .form-group-lg .form-control,.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:25px;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active:focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary.active,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.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;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.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{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group-vertical>.btn:focus,.btn-group>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn>input[type=checkbox],[data-toggle=buttons]>.btn>input[type=radio]{position:absolute;z-index:-1;opacity:0}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#777}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#777}.navbar-inverse .navbar-nav>li>a{color:#777}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#777}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#777}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.nav-pills>.active>a>.badge,a.list-group-item.active>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 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:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar[aria-valuenow="1"],.progress-bar[aria-valuenow="2"]{min-width:30px}.progress-bar[aria-valuenow="0"]{min-width:30px;color:#777;background-color:transparent;background-image:none;-webkit-box-shadow:none;box-shadow:none}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;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{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate3d(0,-25%,0);-o-transform:translate3d(0,-25%,0);transform:translate3d(0,-25%,0)}.modal.in .modal-dialog{-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.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.in{opacity:.5}.modal-header{min-height:16.42857143px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.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}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;opacity:0}.tooltip.in{opacity:.9}.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:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;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-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.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:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.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{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";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,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{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:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}.ng-table th{text-align:center;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ng-table th.sortable{cursor:pointer}.ng-table th.sortable .sort-indicator{padding-right:18px;position:relative}.ng-table th.sortable .sort-indicator:after,.ng-table th.sortable .sort-indicator:before{content:"";border-width:0 4px 4px;border-style:solid;border-color:#000 transparent;visibility:visible;right:5px;top:50%;position:absolute;opacity:.3;margin-top:-4px}.ng-table th.sortable .sort-indicator:before{margin-top:2px;border-bottom:none;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000}.ng-table th.sortable .sort-indicator:hover:after,.ng-table th.sortable .sort-indicator:hover:before{opacity:1;visibility:visible}.ng-table th.sortable.sort-asc,.ng-table th.sortable.sort-desc{background-color:rgba(141,192,219,.25);text-shadow:0 1px 1px rgba(255,255,255,.75)}.ng-table th.sortable.sort-asc .sort-indicator:after,.ng-table th.sortable.sort-desc .sort-indicator:after{margin-top:-2px}.ng-table th.sortable.sort-asc .sort-indicator:before,.ng-table th.sortable.sort-desc .sort-indicator:before{visibility:hidden}.ng-table th.sortable.sort-asc .sort-indicator:after,.ng-table th.sortable.sort-asc .sort-indicator:hover:after{visibility:visible;-khtml-opacity:.6;-moz-opacity:.6;opacity:.6}.ng-table th.sortable.sort-desc .sort-indicator:after{border-bottom:none;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000;visibility:visible;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-khtml-opacity:.6;-moz-opacity:.6;opacity:.6}.ng-table th.filter .input-filter{margin:0;display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.ng-table+.pagination{margin-top:0}@media only screen and (max-width:800px){.ng-table-responsive{border-bottom:1px solid #999}.ng-table-responsive tr{border-top:1px solid #999;border-left:1px solid #999;border-right:1px solid #999}.ng-table-responsive td:before{position:absolute;padding:8px;left:0;top:0;width:50%;white-space:nowrap;text-align:left;font-weight:700}.ng-table-responsive thead tr th{text-align:left}.ng-table-responsive thead tr.ng-table-filters th{padding:0}.ng-table-responsive thead tr.ng-table-filters th form>div{padding:8px}.ng-table-responsive td{border:none;border-bottom:1px solid #eee;position:relative;padding-left:50%;white-space:normal;text-align:left}.ng-table-responsive td:before{content:attr(data-title-text)}.ng-table-responsive,.ng-table-responsive tbody,.ng-table-responsive td,.ng-table-responsive th,.ng-table-responsive thead,.ng-table-responsive tr{display:block}}.select2-container{margin:0;position:relative;display:inline-block;/* inline-block for ie7 */zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;height:26px;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #aaa;white-space:nowrap;line-height:26px;color:#444;text-decoration:none;border-radius:4px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#eee),color-stop(.5,#fff));background-image:-webkit-linear-gradient(center bottom,#eee 0,#fff 50%);background-image:-moz-linear-gradient(center bottom,#eee 0,#fff 50%);background-image:linear-gradient(to top,#eee 0,#fff 50%)}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#aaa;border-radius:0 0 4px 4px;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#eee),color-stop(.9,#fff));background-image:-webkit-linear-gradient(center bottom,#eee 0,#fff 90%);background-image:-moz-linear-gradient(center bottom,#eee 0,#fff 90%);background-image:linear-gradient(to bottom,#eee 0,#fff 90%)}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:8px;font-size:1px;text-decoration:none;border:0;background:url(select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;/* styles required for IE to work */background-color:#fff}.select2-drop{width:100%;margin-top:-1px;position:absolute;z-index:9999;top:100%;background:#fff;color:#000;border:1px solid #aaa;border-top:0;border-radius:0 0 4px 4px;-webkit-box-shadow:0 4px 5px rgba(0,0,0,.15);box-shadow:0 4px 5px rgba(0,0,0,.15)}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #aaa;border-bottom:0;border-radius:4px 4px 0 0;-webkit-box-shadow:0 -4px 5px rgba(0,0,0,.15);box-shadow:0 -4px 5px rgba(0,0,0,.15)}.select2-drop-active{border:1px solid #5897fb;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #5897fb}.select2-drop-auto-width{border-top:1px solid #aaa;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-left:1px solid #aaa;border-radius:0 4px 4px 0;background-clip:padding-box;background:#ccc;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#ccc),color-stop(.6,#eee));background-image:-webkit-linear-gradient(center bottom,#ccc 0,#eee 60%);background-image:-moz-linear-gradient(center bottom,#ccc 0,#eee 60%);background-image:linear-gradient(to top,#ccc 0,#eee 60%)}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-left:none;border-right:1px solid #aaa;border-radius:4px 0 0 4px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;background:url(select2.png) no-repeat 0 1px}html[dir=rtl] .select2-container .select2-choice .select2-arrow b{background-position:2px 1px}.select2-search{display:inline-block;width:100%;min-height:26px;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap}.select2-search input{width:100%;height:auto!important;min-height:26px;padding:4px 20px 4px 5px;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #aaa;border-radius:0;-webkit-box-shadow:none;box-shadow:none;background:#fff url(select2.png) no-repeat 100% -22px;background:url(select2.png) no-repeat 100% -22px,-webkit-gradient(linear,left bottom,left top,color-stop(.85,#fff),color-stop(.99,#eee));background:url(select2.png) no-repeat 100% -22px,-webkit-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2.png) no-repeat 100% -22px,-moz-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2.png) no-repeat 100% -22px,linear-gradient(to bottom,#fff 85%,#eee 99%) 0 0}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:#fff url(select2.png) no-repeat -37px -22px;background:url(select2.png) no-repeat -37px -22px,-webkit-gradient(linear,left bottom,left top,color-stop(.85,#fff),color-stop(.99,#eee));background:url(select2.png) no-repeat -37px -22px,-webkit-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2.png) no-repeat -37px -22px,-moz-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2.png) no-repeat -37px -22px,linear-gradient(to bottom,#fff 85%,#eee 99%) 0 0}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:#fff url(select2-spinner.gif) no-repeat 100%;background:url(select2-spinner.gif) no-repeat 100%,-webkit-gradient(linear,left bottom,left top,color-stop(.85,#fff),color-stop(.99,#eee));background:url(select2-spinner.gif) no-repeat 100%,-webkit-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2-spinner.gif) no-repeat 100%,-moz-linear-gradient(center bottom,#fff 85%,#eee 99%);background:url(select2-spinner.gif) no-repeat 100%,linear-gradient(to bottom,#fff 85%,#eee 99%) 0 0}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #5897fb;outline:0;-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3)}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0;background-color:#eee;background-image:-webkit-gradient(linear,left bottom,left top,color-stop(0,#fff),color-stop(.5,#eee));background-image:-webkit-linear-gradient(center bottom,#fff 0,#eee 50%);background-image:-moz-linear-gradient(center bottom,#fff 0,#eee 50%);background-image:linear-gradient(to top,#fff 0,#eee 50%)}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #5897fb;border-top-color:transparent;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(.5,#eee));background-image:-webkit-linear-gradient(center top,#fff 0,#eee 50%);background-image:-moz-linear-gradient(center top,#fff 0,#eee 50%);background-image:linear-gradient(to bottom,#fff 0,#eee 50%)}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:0 0 0 4px;margin:4px 4px 4px 0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:3px 7px 4px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#3875d7;color:#fff}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:#f4f4f4 url(select2-spinner.gif) no-repeat 100%}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #aaa;cursor:text;overflow:hidden;background-color:#fff;background-image:-webkit-gradient(linear,0 0,0 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(top,#eee 1%,#fff 15%);background-image:-moz-linear-gradient(top,#eee 1%,#fff 15%);background-image:linear-gradient(to bottom,#eee 1%,#fff 15%)}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px 3px 5px!important}.select2-container-multi .select2-choices{min-height:26px}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #5897fb;outline:0;-webkit-box-shadow:0 0 5px rgba(0,0,0,.3);box-shadow:0 0 5px rgba(0,0,0,.3)}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field input{padding:5px;margin:1px 0;font-family:sans-serif;font-size:100%;color:#666;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:#fff url(select2-spinner.gif) no-repeat 100%!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:3px 5px 3px 18px;margin:3px 0 3px 5px;position:relative;line-height:13px;color:#333;cursor:default;border:1px solid #aaa;border-radius:3px;-webkit-box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4;background-image:-webkit-gradient(linear,0 0,0 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(to bottom,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%)}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:3px 18px 3px 5px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:3px;top:4px;font-size:1px;outline:0;background:url(select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:3px}.select2-container-multi .select2-search-choice-close{left:3px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:2px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover{background-position:right -11px}.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px 3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-container .select2-choice .select2-arrow b,.select2-container .select2-choice abbr,.select2-search input,.select2-search-choice-close{background-image:url(select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important}.select2-search input{background-position:100% -21px!important}}/*! + * ui-select + * http://github.com/angular-ui/ui-select + * Version: 0.12.1 - 2015-07-28T03:50:59.080Z + * License: MIT + */.ui-select-highlight{font-weight:700}.ui-select-offscreen{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.ng-dirty.ng-invalid>a.select2-choice{border-color:#d44950}.select2-result-single{padding-left:0}.select2-locked>.select2-search-choice-close{display:none}.select-locked>.ui-select-match-close{display:none}body>.select2-container.open{z-index:9999}.ui-select-container[theme=select2].direction-up .ui-select-match{border-radius:4px;border-top-left-radius:0;border-top-right-radius:0}.ui-select-container[theme=select2].direction-up .ui-select-dropdown{border-radius:4px;border-bottom-left-radius:0;border-bottom-right-radius:0;border-top-width:1px;border-top-style:solid;box-shadow:0 -4px 8px rgba(0,0,0,.25);margin-top:-4px}.ui-select-container[theme=select2].direction-up .ui-select-dropdown .select2-search{margin-top:4px}.ui-select-container[theme=select2].direction-up.select2-dropdown-open .ui-select-match{border-bottom-color:#5897fb}.selectize-input.selectize-focus{border-color:#007fbb!important}.selectize-control>.selectize-input>input{width:100%}.selectize-control>.selectize-dropdown{width:100%}.ng-dirty.ng-invalid>div.selectize-input{border-color:#d44950}.ui-select-container[theme=selectize].direction-up .ui-select-dropdown{box-shadow:0 -4px 8px rgba(0,0,0,.25);margin-top:-2px}.btn-default-focus{color:#333;background-color:#ebebeb;border-color:#adadad;text-decoration:none;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.ui-select-bootstrap .ui-select-toggle{position:relative}.ui-select-bootstrap .ui-select-toggle>.caret{position:absolute;height:10px;top:50%;right:10px;margin-top:-2px}.input-group>.ui-select-bootstrap.dropdown{position:static}.input-group>.ui-select-bootstrap>input.ui-select-search.form-control{border-radius:4px;border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.ui-select-bootstrap>input.ui-select-search.form-control.direction-up{border-radius:4px!important;border-top-right-radius:0!important;border-bottom-right-radius:0!important}.ui-select-bootstrap>.ui-select-match>.btn{text-align:left!important}.ui-select-bootstrap>.ui-select-match>.caret{position:absolute;top:45%;right:15px}.ui-select-bootstrap>.ui-select-choices{width:100%;height:auto;max-height:200px;overflow-x:hidden;margin-top:-1px}body>.ui-select-bootstrap.open{z-index:1000}.ui-select-multiple.ui-select-bootstrap{height:auto;padding:3px 3px 0 3px}.ui-select-multiple.ui-select-bootstrap input.ui-select-search{background-color:transparent!important;border:none;outline:0;height:1.666666em;margin-bottom:3px}.ui-select-multiple.ui-select-bootstrap .ui-select-match .close{font-size:1.6em;line-height:.75}.ui-select-multiple.ui-select-bootstrap .ui-select-match-item{outline:0;margin:0 3px 3px 0}.ui-select-multiple .ui-select-match-item{position:relative}.ui-select-multiple .ui-select-match-item.dropping-before:before{content:"";position:absolute;top:0;right:100%;height:100%;margin-right:2px;border-left:1px solid #428bca}.ui-select-multiple .ui-select-match-item.dropping-after:after{content:"";position:absolute;top:0;left:100%;height:100%;margin-left:2px;border-right:1px solid #428bca}.ui-select-bootstrap .ui-select-choices-row>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.ui-select-bootstrap .ui-select-choices-row>a:focus,.ui-select-bootstrap .ui-select-choices-row>a:hover{text-decoration:none;color:#262626;background-color:#f5f5f5}.ui-select-bootstrap .ui-select-choices-row.active>a{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.ui-select-bootstrap .ui-select-choices-row.active.disabled>a,.ui-select-bootstrap .ui-select-choices-row.disabled>a{color:#777;cursor:not-allowed;background-color:#fff}.ui-select-match.ng-hide-add,.ui-select-search.ng-hide-add{display:none!important}.ui-select-bootstrap.ng-dirty.ng-invalid>button.btn.ui-select-match{border-color:#d44950}.ui-select-container[theme=bootstrap].direction-up .ui-select-dropdown{box-shadow:0 -4px 8px rgba(0,0,0,.25)}.selectize-control.plugin-drag_drop.multi>.selectize-input>div.ui-sortable-placeholder{visibility:visible!important;background:#f2f2f2!important;background:rgba(0,0,0,.06)!important;border:0 none!important;-webkit-box-shadow:inset 0 0 12px 4px #fff;box-shadow:inset 0 0 12px 4px #fff}.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after{content:'!';visibility:hidden}.selectize-control.plugin-drag_drop .ui-sortable-helper{-webkit-box-shadow:0 2px 5px rgba(0,0,0,.2);box-shadow:0 2px 5px rgba(0,0,0,.2)}.selectize-dropdown-header{position:relative;padding:5px 8px;border-bottom:1px solid #d0d0d0;background:#f8f8f8;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.selectize-dropdown-header-close{position:absolute;right:8px;top:50%;color:#303030;opacity:.4;margin-top:-12px;line-height:20px;font-size:20px!important}.selectize-dropdown-header-close:hover{color:#000}.selectize-dropdown.plugin-optgroup_columns .optgroup{border-right:1px solid #f2f2f2;border-top:0 none;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child{border-right:0 none}.selectize-dropdown.plugin-optgroup_columns .optgroup:before{display:none}.selectize-dropdown.plugin-optgroup_columns .optgroup-header{border-top:0 none}.selectize-control.plugin-remove_button [data-value]{position:relative;padding-right:24px!important}.selectize-control.plugin-remove_button [data-value] .remove{z-index:1;position:absolute;top:0;right:0;bottom:0;width:17px;text-align:center;font-weight:700;font-size:12px;color:inherit;text-decoration:none;vertical-align:middle;display:inline-block;padding:2px 0 0 0;border-left:1px solid #0073bb;-webkit-border-radius:0 2px 2px 0;-moz-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-control.plugin-remove_button [data-value] .remove:hover{background:rgba(0,0,0,.05)}.selectize-control.plugin-remove_button [data-value].active .remove{border-left-color:#00578d}.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover{background:0 0}.selectize-control.plugin-remove_button .disabled [data-value] .remove{border-left-color:#aaa}.selectize-control{position:relative}.selectize-dropdown,.selectize-input,.selectize-input input{color:#303030;font-family:inherit;font-size:13px;line-height:18px;-webkit-font-smoothing:inherit}.selectize-control.single .selectize-input.input-active,.selectize-input{background:#fff;cursor:text;display:inline-block}.selectize-input{border:1px solid #d0d0d0;padding:8px 8px;display:inline-block;width:100%;overflow:hidden;position:relative;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.1);box-shadow:inset 0 1px 1px rgba(0,0,0,.1);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.selectize-control.multi .selectize-input.has-items{padding:5px 8px 2px}.selectize-input.full{background-color:#fff}.selectize-input.disabled,.selectize-input.disabled *{cursor:default!important}.selectize-input.focus{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.15)}.selectize-input.dropdown-active{-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.selectize-input>*{vertical-align:baseline;display:-moz-inline-stack;display:inline-block;zoom:1}.selectize-control.multi .selectize-input>div{cursor:pointer;margin:0 3px 3px 0;padding:2px 6px;background:#1da7ee;color:#fff;border:1px solid #0073bb}.selectize-control.multi .selectize-input>div.active{background:#92c836;color:#fff;border:1px solid #00578d}.selectize-control.multi .selectize-input.disabled>div,.selectize-control.multi .selectize-input.disabled>div.active{color:#fff;background:#d2d2d2;border:1px solid #aaa}.selectize-input>input{display:inline-block!important;padding:0!important;min-height:0!important;max-height:none!important;max-width:100%!important;margin:0 1px!important;text-indent:0!important;border:0 none!important;background:0 0!important;line-height:inherit!important;-webkit-user-select:auto!important;-webkit-box-shadow:none!important;box-shadow:none!important}.selectize-input>input::-ms-clear{display:none}.selectize-input>input:focus{outline:0!important}.selectize-input::after{content:' ';display:block;clear:left}.selectize-input.dropdown-active::before{content:' ';display:block;position:absolute;background:#f0f0f0;height:1px;bottom:0;left:0;right:0}.selectize-dropdown{position:absolute;z-index:10;border:1px solid #d0d0d0;background:#fff;margin:-1px 0 0 0;border-top:0 none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.1);-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.selectize-dropdown [data-selectable]{cursor:pointer;overflow:hidden}.selectize-dropdown [data-selectable] .highlight{background:rgba(125,168,208,.2);-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px}.selectize-dropdown .optgroup-header,.selectize-dropdown [data-selectable]{padding:5px 8px}.selectize-dropdown .optgroup:first-child .optgroup-header{border-top:0 none}.selectize-dropdown .optgroup-header{color:#303030;background:#fff;cursor:default}.selectize-dropdown .active{background-color:#f5fafd;color:#495c68}.selectize-dropdown .active.create{color:#495c68}.selectize-dropdown .create{color:rgba(48,48,48,.5)}.selectize-dropdown-content{overflow-y:auto;overflow-x:hidden;max-height:200px}.selectize-control.single .selectize-input,.selectize-control.single .selectize-input input{cursor:pointer}.selectize-control.single .selectize-input.input-active,.selectize-control.single .selectize-input.input-active input{cursor:text}.selectize-control.single .selectize-input:after{content:' ';display:block;position:absolute;top:50%;right:15px;margin-top:-3px;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:grey transparent transparent transparent}.selectize-control.single .selectize-input.dropdown-active:after{margin-top:-4px;border-width:0 5px 5px 5px;border-color:transparent transparent grey transparent}.selectize-control.rtl.single .selectize-input:after{left:15px;right:auto}.selectize-control.rtl .selectize-input>input{margin:0 4px 0 -2px!important}.selectize-control .selectize-input.disabled{opacity:.5;background-color:#fafafa}.selectize-control.multi .selectize-input.has-items{padding-left:5px;padding-right:5px}.selectize-control.multi .selectize-input.disabled [data-value]{color:#999;text-shadow:none;background:0 0;-webkit-box-shadow:none;box-shadow:none}.selectize-control.multi .selectize-input.disabled [data-value],.selectize-control.multi .selectize-input.disabled [data-value] .remove{border-color:#e6e6e6}.selectize-control.multi .selectize-input.disabled [data-value] .remove{background:0 0}.selectize-control.multi .selectize-input [data-value]{text-shadow:0 1px 0 rgba(0,51,83,.3);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;background-color:#1b9dec;background-image:-moz-linear-gradient(top,#1da7ee,#178ee9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#1da7ee),to(#178ee9));background-image:-webkit-linear-gradient(top,#1da7ee,#178ee9);background-image:-o-linear-gradient(top,#1da7ee,#178ee9);background-image:linear-gradient(to bottom,#1da7ee,#178ee9);background-repeat:repeat-x;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 1px rgba(255,255,255,.03);box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 1px rgba(255,255,255,.03)}.selectize-control.multi .selectize-input [data-value].active{background-color:#0085d4;background-image:-moz-linear-gradient(top,#008fd8,#0075cf);background-image:-webkit-gradient(linear,0 0,0 100%,from(#008fd8),to(#0075cf));background-image:-webkit-linear-gradient(top,#008fd8,#0075cf);background-image:-o-linear-gradient(top,#008fd8,#0075cf);background-image:linear-gradient(to bottom,#008fd8,#0075cf);background-repeat:repeat-x}.selectize-control.single .selectize-input{-webkit-box-shadow:0 1px 0 rgba(0,0,0,.05),inset 0 1px 0 rgba(255,255,255,.8);box-shadow:0 1px 0 rgba(0,0,0,.05),inset 0 1px 0 rgba(255,255,255,.8);background-color:#f9f9f9;background-image:-moz-linear-gradient(top,#fefefe,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fefefe),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fefefe,#f2f2f2);background-image:-o-linear-gradient(top,#fefefe,#f2f2f2);background-image:linear-gradient(to bottom,#fefefe,#f2f2f2);background-repeat:repeat-x}.selectize-control.single .selectize-input,.selectize-dropdown.single{border-color:#b8b8b8}.selectize-dropdown .optgroup-header{padding-top:7px;font-weight:700;font-size:.85em}.selectize-dropdown .optgroup{border-top:1px solid #f0f0f0}.selectize-dropdown .optgroup:first-child{border-top:0 none}.am-fade-and-scale{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-scale.am-fade-and-scale-add,.am-fade-and-scale.ng-enter,.am-fade-and-scale.ng-hide-remove,.am-fade-and-scale.ng-move{-webkit-animation-name:fadeAndScaleIn;animation-name:fadeAndScaleIn}.am-fade-and-scale.am-fade-and-scale-remove,.am-fade-and-scale.ng-hide,.am-fade-and-scale.ng-leave{-webkit-animation-name:fadeAndScaleOut;animation-name:fadeAndScaleOut}.am-fade-and-scale.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndScaleIn;animation-name:fadeAndScaleIn;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-scale.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-scale.ng-leave{-webkit-animation-name:fadeAndScaleOut;animation-name:fadeAndScaleOut;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-scale.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes fadeAndScaleIn{from{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}to{opacity:1}}@keyframes fadeAndScaleIn{from{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}to{opacity:1}}@-webkit-keyframes fadeAndScaleOut{from{opacity:1}to{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}}@keyframes fadeAndScaleOut{from{opacity:1}to{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}}.am-fade-and-slide-top{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-slide-top.am-fade-and-slide-top-add,.am-fade-and-slide-top.ng-hide-remove,.am-fade-and-slide-top.ng-move{-webkit-animation-name:fadeAndSlideFromTop;animation-name:fadeAndSlideFromTop}.am-fade-and-slide-top.am-fade-and-slide-top-remove,.am-fade-and-slide-top.ng-hide{-webkit-animation-name:fadeAndSlideToTop;animation-name:fadeAndSlideToTop}.am-fade-and-slide-top.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndSlideFromTop;animation-name:fadeAndSlideFromTop;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-top.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-top.ng-leave{-webkit-animation-name:fadeAndSlideToTop;animation-name:fadeAndSlideToTop;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-top.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-right{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-slide-right.am-fade-and-slide-right-add,.am-fade-and-slide-right.ng-hide-remove,.am-fade-and-slide-right.ng-move{-webkit-animation-name:fadeAndSlideFromRight;animation-name:fadeAndSlideFromRight}.am-fade-and-slide-right.am-fade-and-slide-right-remove,.am-fade-and-slide-right.ng-hide{-webkit-animation-name:fadeAndSlideToRight;animation-name:fadeAndSlideToRight}.am-fade-and-slide-right.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndSlideFromRight;animation-name:fadeAndSlideFromRight;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-right.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-right.ng-leave{-webkit-animation-name:fadeAndSlideToRight;animation-name:fadeAndSlideToRight;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-right.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-bottom{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-slide-bottom.am-fade-and-slide-bottom-add,.am-fade-and-slide-bottom.ng-hide-remove,.am-fade-and-slide-bottom.ng-move{-webkit-animation-name:fadeAndSlideFromBottom;animation-name:fadeAndSlideFromBottom}.am-fade-and-slide-bottom.am-fade-and-slide-bottom-remove,.am-fade-and-slide-bottom.ng-hide{-webkit-animation-name:fadeAndSlideToBottom;animation-name:fadeAndSlideToBottom}.am-fade-and-slide-bottom.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndSlideFromBottom;animation-name:fadeAndSlideFromBottom;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-bottom.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-bottom.ng-leave{-webkit-animation-name:fadeAndSlideToBottom;animation-name:fadeAndSlideToBottom;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-bottom.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-left{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-fade-and-slide-left.am-fade-and-slide-left-add,.am-fade-and-slide-left.ng-hide-remove,.am-fade-and-slide-left.ng-move{-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards;-webkit-animation-name:fadeAndSlideFromLeft;animation-name:fadeAndSlideFromLeft}.am-fade-and-slide-left.am-fade-and-slide-left-remove,.am-fade-and-slide-left.ng-hide{-webkit-animation-name:fadeAndSlideToLeft;animation-name:fadeAndSlideToLeft}.am-fade-and-slide-left.ng-enter{visibility:hidden;-webkit-animation-name:fadeAndSlideFromLeft;animation-name:fadeAndSlideFromLeft;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-left.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade-and-slide-left.ng-leave{-webkit-animation-name:fadeAndSlideToLeft;animation-name:fadeAndSlideToLeft;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade-and-slide-left.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes fadeAndSlideFromTop{from{opacity:0;-webkit-transform:translateY(-20%);transform:translateY(-20%)}to{opacity:1}}@keyframes fadeAndSlideFromTop{from{opacity:0;-webkit-transform:translateY(-20%);transform:translateY(-20%)}to{opacity:1}}@-webkit-keyframes fadeAndSlideToTop{from{opacity:1}to{opacity:0;-webkit-transform:translateY(-20%);transform:translateY(-20%)}}@keyframes fadeAndSlideToTop{from{opacity:1}to{opacity:0;-webkit-transform:translateY(-20%);transform:translateY(-20%)}}@-webkit-keyframes fadeAndSlideFromRight{from{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}to{opacity:1}}@keyframes fadeAndSlideFromRight{from{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}to{opacity:1}}@-webkit-keyframes fadeAndSlideToRight{from{opacity:1}to{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}}@keyframes fadeAndSlideToRight{from{opacity:1}to{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}}@-webkit-keyframes fadeAndSlideFromBottom{from{opacity:0;-webkit-transform:translateY(20%);transform:translateY(20%)}to{opacity:1}}@keyframes fadeAndSlideFromBottom{from{opacity:0;-webkit-transform:translateY(20%);transform:translateY(20%)}to{opacity:1}}@-webkit-keyframes fadeAndSlideToBottom{from{opacity:1}to{opacity:0;-webkit-transform:translateY(20%);transform:translateY(20%)}}@keyframes fadeAndSlideToBottom{from{opacity:1}to{opacity:0;-webkit-transform:translateY(20%);transform:translateY(20%)}}@-webkit-keyframes fadeAndSlideFromLeft{from{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}to{opacity:1}}@keyframes fadeAndSlideFromLeft{from{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}to{opacity:1}}@-webkit-keyframes fadeAndSlideToLeft{from{opacity:1}to{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}}@keyframes fadeAndSlideToLeft{from{opacity:1}to{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}}.am-fade{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards;opacity:1}.am-fade.am-fade-add,.am-fade.ng-hide-remove,.am-fade.ng-move{-webkit-animation-name:fadeIn;animation-name:fadeIn}.am-fade.am-fade-remove,.am-fade.ng-hide{-webkit-animation-name:fadeOut;animation-name:fadeOut}.am-fade.ng-enter{visibility:hidden;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-fade.ng-leave{-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-play-state:paused;animation-play-state:paused}.am-fade.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeOut{from{opacity:1}to{opacity:0}}@keyframes fadeOut{from{opacity:1}to{opacity:0}}.aside-backdrop.am-fade,.modal-backdrop.am-fade{background:rgba(0,0,0,.5);-webkit-animation-duration:.15s;animation-duration:.15s}.aside-backdrop.am-fade.ng-leave,.modal-backdrop.am-fade.ng-leave{-webkit-animation-delay:.3s;animation-delay:.3s}.am-flip-x{-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-flip-x.am-flip-x-add,.am-flip-x.ng-hide-remove,.am-flip-x.ng-move{-webkit-animation-name:flipInXBounce;animation-name:flipInXBounce}.am-flip-x.am-flip-x-remove,.am-flip-x.ng-hide{-webkit-animation-name:flipOutX;animation-name:flipOutX}.am-flip-x.ng-enter{visibility:hidden;-webkit-animation-name:flipInXBounce;animation-name:flipInXBounce;-webkit-animation-play-state:paused;animation-play-state:paused}.am-flip-x.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-flip-x.ng-leave{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-animation-play-state:paused;animation-play-state:paused}.am-flip-x.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-flip-x-linear{-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-flip-x-linear.am-flip-x-add,.am-flip-x-linear.ng-hide-remove,.am-flip-x-linear.ng-move{-webkit-animation-name:flipInX;animation-name:flipInX}.am-flip-x-linear.am-flip-x-remove,.am-flip-x-linear.ng-hide{-webkit-animation-name:flipOutX;animation-name:flipOutX}.am-flip-x-linear.ng-enter{visibility:hidden;-webkit-animation-name:flipInX;animation-name:flipInX;-webkit-animation-play-state:paused;animation-play-state:paused}.am-flip-x-linear.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-flip-x-linear.ng-leave{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-animation-play-state:paused;animation-play-state:paused}.am-flip-x-linear.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes flipInX{from{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}to{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}}@keyframes flipInX{from{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}to{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}}@-webkit-keyframes flipInXBounce{from{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}40%{-webkit-transform:perspective(400px) rotateX(-10deg);transform:perspective(400px) rotateX(-10deg)}70%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg)}to{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}}@keyframes flipInXBounce{from{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}40%{-webkit-transform:perspective(400px) rotateX(-10deg);transform:perspective(400px) rotateX(-10deg)}70%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg)}to{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}}@-webkit-keyframes flipOutX{from{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}to{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}}@keyframes flipOutX{from{opacity:1;-webkit-transform:perspective(400px) rotateX(0);transform:perspective(400px) rotateX(0)}to{opacity:0;-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg)}}.am-slide-top{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-slide-top.am-slide-top-add,.am-slide-top.ng-hide-remove,.am-slide-top.ng-move{-webkit-animation-name:slideFromTop;animation-name:slideFromTop}.am-slide-top.am-slide-top-remove,.am-slide-top.ng-hide{-webkit-animation-name:slideToTop;animation-name:slideToTop}.am-slide-top.ng-enter{visibility:hidden;-webkit-animation-name:slideFromTop;animation-name:slideFromTop;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-top.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-slide-top.ng-leave{-webkit-animation-name:slideToTop;animation-name:slideToTop;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-top.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-slide-right{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-slide-right.am-slide-right-add,.am-slide-right.ng-hide-remove,.am-slide-right.ng-move{-webkit-animation-name:slideFromRight;animation-name:slideFromRight}.am-slide-right.am-slide-right-remove,.am-slide-right.ng-hide{-webkit-animation-name:slideToRight;animation-name:slideToRight}.am-slide-right.ng-enter{visibility:hidden;-webkit-animation-name:slideFromRight;animation-name:slideFromRight;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-right.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-slide-right.ng-leave{-webkit-animation-name:slideToRight;animation-name:slideToRight;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-right.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-slide-bottom{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-slide-bottom.am-slide-bottom-add,.am-slide-bottom.ng-hide-remove,.am-slide-bottom.ng-move{-webkit-animation-name:slideFromBottom;animation-name:slideFromBottom}.am-slide-bottom.am-slide-bottom-remove,.am-slide-bottom.ng-hide{-webkit-animation-name:slideToBottom;animation-name:slideToBottom}.am-slide-bottom.ng-enter{visibility:hidden;-webkit-animation-name:slideFromBottom;animation-name:slideFromBottom;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-bottom.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-slide-bottom.ng-leave{-webkit-animation-name:slideToBottom;animation-name:slideToBottom;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-bottom.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}.am-slide-left{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-fill-mode:backwards;animation-fill-mode:backwards}.am-slide-left.am-slide-left-add,.am-slide-left.ng-hide-remove,.am-slide-left.ng-move{-webkit-animation-name:slideFromLeft;animation-name:slideFromLeft}.am-slide-left.am-slide-left-remove,.am-slide-left.ng-hide{-webkit-animation-name:slideToLeft;animation-name:slideToLeft}.am-slide-left.ng-enter{visibility:hidden;-webkit-animation-name:slideFromLeft;animation-name:slideFromLeft;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-left.ng-enter.ng-enter-active{visibility:visible;-webkit-animation-play-state:running;animation-play-state:running}.am-slide-left.ng-leave{-webkit-animation-name:slideToLeft;animation-name:slideToLeft;-webkit-animation-play-state:paused;animation-play-state:paused}.am-slide-left.ng-leave.ng-leave-active{-webkit-animation-play-state:running;animation-play-state:running}@-webkit-keyframes slideFromTop{from{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@keyframes slideFromTop{from{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@-webkit-keyframes slideToTop{to{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@keyframes slideToTop{to{-webkit-transform:translateY(-100%);transform:translateY(-100%)}}@-webkit-keyframes slideFromRight{from{-webkit-transform:translateX(100%);transform:translateX(100%)}}@keyframes slideFromRight{from{-webkit-transform:translateX(100%);transform:translateX(100%)}}@-webkit-keyframes slideToRight{to{-webkit-transform:translateX(100%);transform:translateX(100%)}}@keyframes slideToRight{to{-webkit-transform:translateX(100%);transform:translateX(100%)}}@-webkit-keyframes slideFromBottom{from{-webkit-transform:translateY(100%);transform:translateY(100%)}}@keyframes slideFromBottom{from{-webkit-transform:translateY(100%);transform:translateY(100%)}}@-webkit-keyframes slideToBottom{to{-webkit-transform:translateY(100%);transform:translateY(100%)}}@keyframes slideToBottom{to{-webkit-transform:translateY(100%);transform:translateY(100%)}}@-webkit-keyframes slideFromLeft{from{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@keyframes slideFromLeft{from{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@-webkit-keyframes slideToLeft{to{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@keyframes slideToLeft{to{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}.switchery{background-color:#fff;border:1px solid #dfdfdf;border-radius:20px;cursor:pointer;display:inline-block;height:30px;position:relative;vertical-align:middle;width:50px}.switchery>small{background:#fff;border-radius:100%;box-shadow:0 1px 3px rgba(0,0,0,.4);height:30px;position:absolute;top:0;width:30px}.toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#fff}.toast-message a:hover{color:#ccc;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#fff;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;opacity:.8}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-center{top:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-center{bottom:12px}.toast-bottom-left{bottom:12px;left:12px}.toast-center{top:45%}#toast-container{position:fixed;z-index:999999}#toast-container.toast-bottom-center,#toast-container.toast-center,#toast-container.toast-top-center{width:100%;pointer-events:none}#toast-container.toast-bottom-center>div,#toast-container.toast-center>div,#toast-container.toast-top-center>div{margin:auto;pointer-events:auto}#toast-container.toast-bottom-center>button,#toast-container.toast-center>button,#toast-container.toast-top-center>button{pointer-events:auto}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px 3px 3px 3px;-webkit-border-radius:3px 3px 3px 3px;border-radius:3px 3px 3px 3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#fff;opacity:.8}#toast-container>:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-wait{background-image:url(data:image/gif;base64,R0lGODlhIAAgAIQAAAQCBISGhMzKzERCROTm5CQiJKyurHx+fPz+/ExOTOzu7Dw+PIyOjCwqLFRWVAwKDIyKjMzOzOzq7CQmJLy6vFRSVPTy9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCQAXACwAAAAAIAAgAAAF3eAljmRpnmh6VRSVqLDpIDTixOdUlFSNUDhSQUAT7ES9GnD0SFQAKWItMqr4bqKHVPDI+WiTkaOFFVlrFe83rDrT0qeIjwrT0iLdU0GOiBxhAA4VeSk6QYeIOAsQEAuJKgw+EI8nA18IA48JBAQvFxCXDI8SNAQikV+iiaQIpheWX5mJmxKeF6g0qpQmA4yOu8C7EwYWCgZswRcTFj4KyMAGlwYxDwcHhCXMXxYxBzQHKNo+3DDeCOAn0V/TddbYJA0K48gAEAFQicMWFsfwNA3JSgAIAAFfwIMIL4QAACH5BAkJABoALAAAAAAgACAAhAQCBIyKjERCRMzOzCQiJPTy9DQyNGRmZMTCxOTm5CwqLHx+fBQWFJyenNTW1Pz6/Dw6PGxubAwKDIyOjNTS1CQmJCwuLPz+/Dw+PHRydAAAAAAAAAAAAAAAAAAAAAAAAAXboCaOZGmeaKoxWcSosMkk15W8cZ7VdZaXkcEgQtrxfD9RhHchima1GwlCGUBSFCaFxMrgRtnLFhWujWHhs2nJc8KoVlWGQnEn7/i8XgOwWAB7JwoONQ4KgSQAZRcOgHgSCwsSIhZMNRZ5CzULIgaWF5h4mhecfIQ8jXmQkiODhYeIiRYGjrG2PxgBARi3IhNMAbcCnwI5BAQpAZ8TIwK6vCQVDwUVKL+WzAANTA210g/VJ8OWxQefByQE4dZMzBoInwh4zrtgn2p725YNthUFTNRuGYB3AYGBHCEAACH5BAkJAB0ALAAAAAAgACAAhAQCBISChFRWVMzKzCQiJOTm5GxqbCwuLJSWlPz6/NTW1AwODJSSlGRmZCwqLOzu7HR2dDQ2NAQGBISGhFxaXNTS1CQmJOzq7GxubDQyNKSmpPz+/Nza3AAAAAAAAAAAAAXfYCeOZGmeaKqurHBdAiuP17Zdc0lMAVHWt9yI8LA9fCPB4xEjARoNSWpis01kBpshFahurqzsZosiGpErScMAUO0maKF8Tq/bTQCIQgFp30cQXhB1BHEcXhx0FgkJFiOHVYlzi42AgoRxeRx8fn+en3UABwedKgsBAwMBCygOCjYKDisLFV4VrCUAtVUKpSZdXl8mB8EbByQWcQPFAyYZxccdB7sV0cvBzbmvvG0LBV4FrFTBYCWuNhyyHRTFFB20trh4BxmdYl4YIqepq0IRxRE+IfDCAFQHARo0NGERAgAh+QQJCQAgACwAAAAAIAAgAIUEAgSEgoRMTkzMyswcHhzk5uR0cnQUFhRcXlwsKiz09vQMCgyMiozU1tQkJiR8fnxkZmT8/vwEBgSEhoRcWlzU0tQkIiT08vR0dnQcGhxkYmQ0MjT8+vwMDgyMjozc2twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG+UCQcEgsGo/IpHLJXDweC6Z0+IhEHlOjRGIMWLHZoUZx0RQlAajxkFFKFFYFl5m5KNpIySU+X2bIBEoQZBBZGQdMElFhjI2Oj5AgHQEDAw8dQxYeDBaNHRVWVhWYCXsRFwmMXqFWEyAerB6MA6xWA6+xs7URt6VWqIwTu64gDh4eDp6goaORQ5OVAZjO1EgEGhB4RwAYDQ0YAEwIcBEKFEgYrBhLBORxgUYfrB9LELuF8fNDAAaVBuEg7NXCVyRdqHVCGLBiIIQAB1Yc4BXh9uEbwAXuyi2iQI7DuSwHdiFqCEGDtizLRFUDsaGAlQIbVoJYIEDAIiZBAAAh+QQJCQAbACwAAAAAIAAgAIQEAgSMioxcWlz08vQcHhysqqwMDgx8enwsKiykoqRkZmT8+vzEwsQMCgyUlpQkJiS0srQEBgSMjoxcXlz09vQkIiSsrqwUEhQ0MjRsamz8/vwAAAAAAAAAAAAAAAAAAAAF7+AmjmRpnmiqruz2PG0sIssCj4CQJAIgj4/abRNJaI6agu9kCAQaphdJgEQKUIFjgGWsahJYLdf7RTWfLKr3+jsBClVlG5Xb9eb4fImgUBBKDVB4ExRHFGwbGRQLGXMEhUgUfw2QC4IyCmSNDQtHlm2ZXgoiGQsUjW0EnUgLfyKBeYSeiHojfH61uS0GBisVEgEVLRcWRxAXKAgDRwMILMVIECgSVRIrBmS9JtRI1iMVBweuGxerSNolyszOIhjLGs0jEFXSKA8SEkMbcEgWIxfzNBxrw6AKgxIGkM05UOWALhERHJhysOThBgAVWYQAACH5BAkJABkALAAAAAAgACAAhAQGBIyKjERCRMzOzCwuLGRiZPz6/OTm5AwODLSytFRSVNTW1Dw6PHx6fAwKDJSSlERGRNTS1DQyNGxqbPz+/BQSFLy6vFRWVNza3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAXqYCaO5FgFwxBUZeu61ULNFMa+eBvQdJD/owFvFhkBBAwHsBQZUooZyWF2YOQkBNJu6ANMaQeli0AxSEwymi0DcUJeEgPlbEJFAghRe/h+Eeg/Dl9UYks5DF9VhksOAgKFi5GSSwh5kzgVCXIJNxknD5aSCTwJIw8zD5MITpanFKmSCHI8NxUPoJejNKWXLZkznL0vCJ3CxsckDpA/ChYJFzkTBgYTSxc80C4OswbLLhY8Fi/bMwYAJVgl4DTiL9LUJADrFuci1zTZLwD1IwU8BSQuWLCQb1EDHg2QiSDALYvCDAISJLDy8FIIACH5BAkJAB4ALAAAAAAgACAAhAQGBISGhFRSVNTW1CQiJKyqrGRmZOzu7CwuLIyOjGxubPz6/BQSFGRiZOTi5CwqLLy6vDQ2NIyKjFRWVCQmJKyurGxqbPT29DQyNJSSlHRydPz+/BQWFOzq7AAAAAAAAAXhoCeOJElYClGubOs117YtjWuvxCLLi3qbhc6h4FPsdorfiNI5dige43GT9AAkHUcCwCpMNxVP7tgTJY4J1uF7EBl0M8Ooueuo2SOCIkVa11kVX2E2EmgsFH4yBz4uAAkdHVstBAUHQ4xKmZqbnJ2bAhAQAiURGJ4eE0cTIxgzpp0QRxCsrp6xO7MjpaepO6unKxOhv8DFxsfIJBwaChw2DAkZDEocDjIOzi0ZMhlKUjIaLtsb3T8aR+EtDBkJ0yQUBQVQI9XX2ZsDMgMlyxr3mzE2XEgmotCGAARFIHiQ0FMIACH5BAkJABgALAAAAAAgACAAhAQCBISGhDw+POTi5CwuLLS2tPTy9BQSFJyenGRiZDQ2NIyOjLy+vPz6/BweHIyKjFRSVOzq7DQyNLy6vBQWFHRydDw6PPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXICaOZHkcZaquIjVd10SxtFrAcFGrVhBYIwoON9uNAsOA6DCEFTEKBEKxEjQvAtELNxkpGrAGNfW4Plpb2QgxRKjKzfPoVGLj3CnLNUv7hscpSDhKOxJSgDwPP0ZGAACMjAQFDQYFBJA0BAZDBpeYGBQVFUU3TV2YFAMwAzNgTQ2PkBVDFRiuQ7CYszi1pUOnkKmrM5qcnqiiTwQTDQ2Wn9DR0tPUfRKQEBEREDQSFw3XRhEwEd3f4TvjF+XWKgJ8JNnb0QkwCdUlCzAL+CQODAwc9BtIMAQAOw==)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin:auto}.toast{background-color:#030303}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-wait{background-color:#2f96b4}.toast-warning{background-color:#f89406}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container .toast-close-button{right:-.2em;top:-.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}}:not(.no-enter)#toast-container>div.ng-enter,:not(.no-leave)#toast-container>div.ng-leave{-webkit-transition:1s cubic-bezier(.25,.25,.75,.75) all;-moz-transition:1s cubic-bezier(.25,.25,.75,.75) all;-ms-transition:1s cubic-bezier(.25,.25,.75,.75) all;-o-transition:1s cubic-bezier(.25,.25,.75,.75) all;transition:1s cubic-bezier(.25,.25,.75,.75) all}:not(.no-enter)#toast-container>div.ng-enter.ng-enter-active,:not(.no-leave)#toast-container>div.ng-leave{opacity:.8}:not(.no-enter)#toast-container>div.ng-enter,:not(.no-leave)#toast-container>div.ng-leave.ng-leave-active{opacity:0}html{overflow:auto;height:100%;margin:0;padding:0}body{height:100%;margin:0;padding:0;color:#323232;font-family:Arial,Helvetica,sans-serif;font-size:1em}div,input,li,span,td,textarea{font-size:1em}.container{font-size:1.2em}.footer{margin:1em 0 1em 0}input[disabled],textarea[disabled]{background-color:#f6f6f6}.strong,strong{font-weight:700}.likeH2,h1,h2,h3{color:#f60;text-align:center}h1{font-size:2em;margin:0}.likeH2,h2{font-size:1.8em;font-weight:lighter;line-height:1em;margin:0 0 1em}h3{font-size:1.6em;font-weight:lighter;line-height:1em;margin:0 0 1em;text-align:left}img{border:none;vertical-align:middle}.banner{margin:1.5em 0 1.5em 0}.sub-banner{margin:0 0 1.5em 0}.underlined{text-decoration:underline}.header img{float:left}.header h1{position:relative}hr{margin-top:10px;margin-bottom:10px}.table{text-align:left!important}.centered{text-align:center;color:#cbcbcb}.customTables,.dropdown-menu{text-align:left!important}.resourceCombo{width:100%}.top05{margin-top:.5em}.top10{margin-top:1em}.top15{margin-top:1.5em}.top20{margin-top:2em}.top25{margin-top:2.5em}.top30{margin-top:3em}.left05{margin-left:.5em}.left10{margin-left:1em}.left15{margin-left:1.5em}.left20{margin-left:2em}.left25{margin-left:2.5em}.left30{margin-left:3em}.black{color:#333}.divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5} \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot b/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 00000000..4a4ca865 Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.eot differ diff --git a/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg b/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 00000000..e3e2dc73 --- /dev/null +++ b/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf b/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 00000000..67fa00bf Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.ttf differ diff --git a/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff b/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 00000000..8c54182a Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/fonts/glyphicons-halflings-regular.woff differ diff --git a/moonv4/moon_gui/delivery/assets/i18n/en.json b/moonv4/moon_gui/delivery/assets/i18n/en.json new file mode 100755 index 00000000..fb0a0774 --- /dev/null +++ b/moonv4/moon_gui/delivery/assets/i18n/en.json @@ -0,0 +1,1266 @@ +{ + "moon": { + "global": { + "applicationName": "Moon", + "404": "Page not found", + "error": "A global error occurs: {{stacktrace}}" + }, + "compatibility": { + "label": "Browsers compatibility", + "title": "Existing browsers compatibility", + "content": "Moon is compliant with : ", + "close": "Close" + }, + "menu": { + "project": "Project", + "pdp": "PDP", + "logs": "Log", + "policy": "Policy", + "model":"Model" + }, + "login":{ + "title" : "Login", + "titlePage" : "Login page", + "username" : "Username", + "password" : "Password", + "login": "Login", + "check": { + "username": { + "required": "Username is required" + }, + "password": { + "required": "Password is required" + } + }, + "error" :"Unable to login into Keystone, error code : {{errorCode}}", + "success" : "Connection established. Welcome to Moon GUI, \"Moon is uppon cloud\"" + }, + "logout": { + "title": "Logout", + "success" : "Successfully logout" + }, + "dashboard":{ + "content" : "Moon:Software-Defined Security Framework" + }, + "policy":{ + "title": "Policies", + "list" : { + "search": { + "placeholder": "Search Policies", + "reset": "Reset" + }, + "table" : { + "name":"Name", + "genre" : "Genre", + "description": "Description", + "loading": { + "category" : "Loading Category" + }, + "notFound": "There is no Policy" + }, + "action": { + "title": "Actions", + "add": "Add Policy", + "detail": "Consut", + "edit": "Edit", + "map" : "Map Policy to PDP", + "unmap" : "Unmap", + "delete": "Delete" + } + }, + "unmap": { + "title": "Unmap Policy to PDP", + "content": "Are you sure you want to unmap PDP `{{pdpName}}` / Policy `{{policyName}}` ?", + "action": { + "unmap": "Unmap", + "cancel": "Cancel" + }, + "error": "Unable to unmap PDP `{{pdpName}}` /Policy `{{policyName}}`", + "success": "PDP `{{pdpName}}` / Policy `{{policyName}}` successfully unmapped" + }, + "map":{ + "title": "Map a Policy to PDP `{{pdpName}}`", + "form" :{ + "list": "List of Policies" + }, + "action": { + "create": "Map Policy", + "cancel": "Cancel", + "new": "Create a Policy", + "list": "Map an existing Policy", + "map": "Map the selected Policy", + "delete" : "Delete the selected Policy" + }, + "check": { + "policy":{ + "required" : "Policy is required" + } + }, + "error": "Unable to map Policy `{{policyName}}` to the PDP `{{pdpName}}`", + "success": "Policy `{{policyName}}` successfully mapped to the PDP `{{pdpName}}`" + }, + "remove": { + "title": "Delete Policy", + "content": { + "query": "Are you sure you want to delete `{{policyName}}` Policy ?" + }, + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Policy `{{policyName}}`, error code : {{errorCode}}, message : \"{{message}}\"", + "success": "Model `{{policyName}}` successfully deleted" + }, + "edit" : { + "title": "Policy `{{policyName}}` configuration", + "update" : "- update", + "show": { + "open": "( show )", + "close": "( close )" + }, + "basic" : { + "title" : "Basic Information", + "form": { + "id": "Id", + "name": "Name", + "genre": "Genre", + "model": "Model", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Update" + }, + "check": { + "name": { + "required": "Name is required" + }, + "genre": { + "required": "Genre is required" + } + }, + "error": "Unable to update Policy `{{policyName}}`", + "success": "Policy `{{policyName}}` successfully updated" + }, + "perimeter": { + "title" : "Perimeters" + }, + "data": { + "title" : "Data" + }, + "rules" : { + "title" : "Rules" + }, + "assignments": { + "title" : "Assignments" + } + }, + "add":{ + "title": "Add new Policy", + "form": { + "name": "Name", + "genre": "Genre", + "model": "Models", + "description": "Description" + }, + "action": { + "create": "Create Policy", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + }, + "genre": { + "required": "Genre is required" + }, + "model": { + "required": "Model is required" + } + }, + "error": "Unable to create Policy `{{policyName}}`", + "success": "Policy `{{policyName}}` successfully created" + }, + "perimeter": { + "subject" : { + "title" : "List of associated Subjects", + "delete": { + "error" : "Unable to delete {{subjectName}} Subject, reason : {{reason}}", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "add": { + "title": "Add a Subject" + }, + "notFound": "There is no Subject" + }, + "object" : { + "title" : "List of associated Objects", + "delete": { + "error" : "Unable to delete {{objectName}} Object, reason : {{reason}}", + "success": "Object `{{objectName}}` successfully deleted" + }, + "add": { + "title": "Add an Object" + }, + "notFound": "There is no Object" + }, + "action" : { + "title" : "List of associated Actions", + "delete": { + "error" : "Unable to delete {{actionName}} Action, reason : {{reason}}", + "success": "Action `{{actionName}}` successfully deleted" + }, + "add": { + "title": "Add an Action" + }, + "notFound": "There is no Action" + }, + "table": { + "id" : "Id", + "name" : "Name", + "description" : "Description", + "email" : "Email", + "partner":{ + "id" : "Partner Id" + }, + "action": { + "title": "Actions", + "delete": "Delete", + "update": "Update" + } + }, + "edit": { + "name" : "Name", + "description" : "Description", + "check": { + "name": { + "required": "Name is required" + } + }, + "action": { + "list": "Map an existing", + "new": "Create a new", + "create": "Create", + "map": "Map the selected", + "delete": "Delete" + }, + "create":{ + "error": "Unable to create `{{name}}`", + "success": "`{{name}}` successfully created" + }, + "delete":{ + "error": "Unable to delete `{{name}}`", + "success": "`{{name}}` successfully deleted" + } + } + }, + "data": { + "subject" : { + "title" : "List of associated Data Subjects", + "delete": { + "error" : "Unable to delete {{subjectName}} Subject, reason : {{reason}}", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "add": { + "title": "Add a Data Subject" + }, + "notFound": "There is no Data Subject" + }, + "object" : { + "title" : "List of associated Data Objects", + "delete": { + "error" : "Unable to delete {{objectName}} Object, reason : {{reason}}", + "success": "Object `{{objectName}}` successfully deleted" + }, + "add": { + "title": "Add a Data Object" + }, + "notFound": "There is no Data Object" + }, + "action" : { + "title" : "List of associated Actions", + "delete": { + "error" : "Unable to delete {{actionName}} Action, reason : {{reason}}", + "success": "Action `{{actionName}}` successfully deleted" + }, + "add": { + "title": "Add a Data Action" + }, + "notFound": "There is no Data Action" + }, + "table": { + "category" : { + "id" : "Category Id", + "name" : "Category Name" + }, + "name" : "Name", + "description" : "Description", + "action": { + "title": "Actions", + "delete": "Delete", + "update": "Update" + }, + "loading": { + "category" : "Loading Category" + } + }, + "edit": { + "name" : "Name", + "description" : "Description", + "check": { + "name": { + "required": "Name is required" + } + }, + "action": { + "list": "Map an existing", + "new": "Create a new", + "create": "Create", + "map": "Map the selected", + "delete": "Delete" + }, + "create":{ + "error": "Unable to create `{{name}}`", + "success": "`{{name}}` successfully created" + }, + "delete":{ + "error": "Unable to delete `{{name}}`", + "success": "`{{name}}` successfully deleted" + } + } + }, + "rules": { + "title": "Rules", + "list": { + "search": { + "placeholder": "Search Rule", + "reset": "Reset" + }, + "table": { + "id" : "Id", + "metaRule": "Meta Rule", + "description": "Description", + "enabled": "Enabled", + "rule": "Rule", + "notFound": "There is no Rule", + "loading": { + "metaRule" : "Loading Meta Rule" + } + }, + "action": { + "title": "Actions", + "add": "Add Rule", + "detail": "Consult", + "edit": "Edit", + "delete": "Delete" + }, + "error": "Unable to retrieve Rule" + } + }, + "assignments": { + "subject" : { + "title" : "List of associated Assignments Subjects", + "delete": { + "error" : "Unable to delete {{subjectName}} Subject, reason : {{reason}}", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "add": { + "title": "Add a Assignments Subject" + }, + "notFound": "There is no Assignments Subject" + }, + "object" : { + "title" : "List of associated Assignments Objects", + "delete": { + "error" : "Unable to delete {{objectName}} Object, reason : {{reason}}", + "success": "Object `{{objectName}}` successfully deleted" + }, + "add": { + "title": "Add a Assignments Object" + }, + "notFound": "There is no Assignments Object" + }, + "action" : { + "title" : "List of associated Assignments Actions", + "delete": { + "error" : "Unable to delete {{actionName}} Action, reason : {{reason}}", + "success": "Action `{{actionName}}` successfully deleted" + }, + "add": { + "title": "Add a Assignments Action" + }, + "notFound": "There is no Assignments Action" + }, + "table": { + "action": { + "title": "Actions", + "delete": "Delete", + "update": "Update" + }, + "perimeter": { + "name" : "Perimeter name" + }, + "data": { + "name": "Data name" + }, + "category": { + "name" : "Category name" + }, + "loading": { + "category" : "Loading Category", + "perimeter": "Loading Perimeter", + "data": "Loading Data" + } + }, + "edit": { + "name" : "Name", + "description" : "Description", + "check": { + "name": { + "required": "Name is required" + } + }, + "action": { + "list": "Map an existing", + "new": "Create a new", + "create": "Create", + "map": "Map the selected", + "delete": "Delete" + }, + "create":{ + "error": "Unable to create `{{name}}`", + "success": "`{{name}}` successfully created" + }, + "delete":{ + "error": "Unable to delete `{{name}}`", + "success": "`{{name}}` successfully deleted" + } + } + } + }, + "model":{ + "title": "Models", + "list": { + "search": { + "placeholder": "Search Model", + "reset": "Reset" + }, + "table":{ + "name":"Name", + "description": "Description", + "metaRules":{ + "number" : "Number of Meta Rules" + }, + "notFound": "There is no Models" + }, + "action": { + "title": "Actions", + "add": "Add Model", + "detail": "Consult", + "edit": "Edit", + "delete": "Delete" + }, + "error": "Unable to retrieve Models" + }, + "edit" : { + "title": "Model `{{modelName}}` configuration", + "update" : "- update", + "basic" : { + "title" : "Basic Information", + "form": { + "id": "Id", + "name": "Name", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Update" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to update Model `{{modelName}}`", + "success": "Model `{{modelName}}` successfully updated" + }, + "metarules": { + "title" : "Meta Rules" + } + }, + "view": { + "title": "Model `{{modelName}}` details", + "name": "Name", + "id": "Id", + "description": "Description", + "action": { + "close": "Close" + } + }, + "remove": { + "title": "Delete Model", + "content": { + "query": "Are you sure you want to delete `{{modelName}}` Model ?" + }, + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Model `{{modelName}}`, error code : {{errorCode}}, message : \"{{message}}\"", + "success": "Model `{{modelName}}` successfully deleted" + }, + "metarules": { + "title": "List of Meta Rules", + "table": { + "name":"Name", + "description": "Description", + "metadata": { + "subject": { + "number": "Number of Subject Categories" + }, + "object" : { + "number": "Number of Object Categories" + }, + "action": { + "number": "Number of Action Categories" + } + }, + "notFound": "There is no Meta Rules" + }, + "edit" : { + "title" : "Meta Rule `{{metaRuleName}}` configuration", + "update": "- update", + "basic": { + "title": "Basic Information", + "form": { + "id": "Id", + "name": "Name", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Update" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to update Meta Rule `{{metaRuleName}}`", + "success": "Meta Rule `{{metaRuleName}}` successfully updated" + } + }, + "update":{ + "error": "Unable to update Meta Rule `{{metaRuleName}}`", + "success": "Meta Rule `{{metaRuleName}}` successfully updated" + }, + "action": { + "title": "Actions", + "edit": "Edit", + "remove": "Remove", + "settings" : "Settings", + "add": "Add", + "detail": { + "open": "Consult", + "close": "Close" + } + }, + "add": { + "title": "Add new Meta Rule", + "form": { + "name": "Nom", + "description": "Description" + }, + "action": { + "create": "Add Meta Rule", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to create Meta Rule `{{metaRuleName}}`", + "success": "Meta Rule `{{metaRuleName}}` successfully created" + }, + "map":{ + "title": "Add a Meta Rule", + "form" :{ + "list": "List of Meta Rules" + }, + "action": { + "create": "Add a new Meta Rule", + "cancel": "Cancel", + "new": "Add a Meta Rule", + "list": "Add an existing Meta Rule", + "add": "Add the selected Meta Rule", + "delete" : "Delete the selected Meta Rule" + }, + "error": "Unable to map Model `{{modelName}}` to the Meta Rule `{{metaRuleName}}`", + "success": "Model `{{modelName}}` successfully mapped to the Meta Rule `{{metaRuleName}}`" + }, + "unmap": { + "title": "Remove Meta Rule to Model", + "content": "Are you sure you want to remove Model `{{modelName}}` / Meta Rule `{{metaRuleName}}` ?", + "action": { + "unmap": "Remove", + "cancel": "Cancel" + }, + "error": "Unable to remove Model `{{modelName}}` / Meta Rule `{{metaRuleName}}`", + "success": "Model `{{modelName}}` / Meta Rule `{{metaRuleName}}` successfully removed" + }, + "delete":{ + "error": "Unable to delete Meta Rule `{{metaRuleName}}`", + "success": "Meta Rule `{{metaRuleName}}` successfully deleted" + } + }, + "metadata": { + "subject" : { + "title" : "List of associated Subject Categories", + "delete": { + "error" : "Unable to delete {{subjectName}} Subject, reason : {{reason}}", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "add": { + "title": "Add a Subject Category" + }, + "notFound": "There is no Subject" + }, + "object" : { + "title" : "List of associated Object Categories", + "delete": { + "error" : "Unable to delete {{objectName}} Object, reason : {{reason}}", + "success": "Object `{{objectName}}` successfully deleted" + }, + "add": { + "title": "Add an Object Category" + }, + "notFound": "There is no Object" + }, + "action" : { + "title" : "List of associated Action Categories", + "remove": "Remove", + "delete": { + "error" : "Unable to delete {{actionName}} Action, reason : {{reason}}", + "success": "Action `{{actionName}}` successfully deleted" + }, + "add": { + "title": "Add an Action Category" + }, + "notFound": "There is no Action" + }, + "table": { + "id" : "Id", + "name" : "Name", + "description" : "Description", + "action": { + "title": "Actions", + "delete": "Delete", + "update": "Update" + } + }, + "edit": { + "name" : "Name", + "description" : "Description", + "check": { + "name": { + "required": "Name is required" + } + }, + "action": { + "list": "Add an existing Category", + "new": "Add a new Category", + "create": "Add Category", + "add": "Add the selected Category", + "delete": "Delete" + }, + "create":{ + "error": "Unable to create Category `{{name}}`", + "success": "Category `{{name}}` successfully created" + }, + "delete":{ + "error": "Unable to delete Category `{{name}}`", + "success": "Category `{{name}}` successfully deleted" + } + } + }, + "add":{ + "title": "Add new Model", + "form": { + "name": "Name", + "description": "Description" + }, + "action": { + "create": "Create Model", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to create Model `{{modelName}}`", + "success": "Model `{{modelName}}` successfully created" + } + }, + "project": { + "title": "Projects", + "list": { + "search": { + "placeholder": "Search Projects", + "reset": "Reset" + }, + "table": { + "name": "Name", + "domain": "Domain", + "managed": "Managed", + "enabled": "Enabled", + "description": "Description", + "mapping": "PDP", + "loading": { + "project": "Loading Projects", + "pdp": "Loading PDP" + }, + "notFound": "There is no Projects" + }, + "action": { + "title": "Actions", + "detail": "Consult", + "delete": "Delete", + "add": "Add Project", + "map": "Map to a PDP", + "unmap": "Unmap" + }, + "error": "Unable to retrieve Projects" + }, + "view": { + "title": "Project `{{projectName}}` details", + "action": { + "close": "Close" + }, + "subject": { + "title": "Subjects", + "name": "Name", + "mail": "Email", + "domain": "Domain", + "enabled": "Enabled", + "error": "Unable to retrieve Subjects" + }, + "object": { + "title": "Objects", + "category": "Category", + "description": "Description", + "enabled": "Enabled", + "name": "Name", + "error": "Unable to retrieve Objects", + "loading": "Loading Objects", + "notFound": "There is no Objects" + }, + "role": { + "title": "Roles", + "category": "Category", + "value": "Value", + "description": "Description", + "assigned": "Assigned", + "enabled": "Enabled", + "error": "Unable to retrieve Roles", + "loading": "Loading Roles", + "notFound": "There is no Roles" + }, + "roleAssignment": { + "title": "Role Assignments", + "category": "Category", + "attributes": "Attributes", + "description": "Description", + "error": "Unable to retrieve Role Assignments", + "loading": "Loading Role Assignments", + "notFound": "There is no Role Assignments" + }, + "group": { + "title": "Groups", + "category": "Category", + "value": "Value", + "description": "Description", + "assigned": "Assigned", + "enabled": "Enabled", + "error": "Unable to retrieve Groups", + "loading": "Loading Groups", + "notFound": "There is no Groups" + }, + "groupAssignment": { + "title": "Group Assignments", + "category": "Category", + "attributes": "Attributes", + "description": "Description", + "error": "Unable to retrieve Group Assignments", + "loading": "Loading Group Assignments", + "notFound": "There is no Group Assignments" + } + }, + "add": { + "title": "Add new Project", + "form": { + "name": "Name", + "description": "Description", + "enabled": "Enabled", + "domain": "Domain" + }, + "action": { + "create": "Create Project", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + }, + "domain": { + "required": "Domain is required" + } + }, + "error": "Unable to create Project `{{projectName}}`", + "success": "Project `{{projectName}}` successfully created" + }, + "remove": { + "title": "Delete Project", + "content": { + "query": "Are you sure you want to delete `{{projectName}}` Project ?", + "isNotMapped": "This Project is not mapped to any PDP", + "isMapped": "This project is mapped to `{{pdpName}}` PDP, delete this Project, will remove the mapping." + }, + "mapping":{ + "remove":{ + "error": "Unable to remove mapping with Pdp : `{{pdpName}}`" + } + }, + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Project `{{projectName}}`, error code : {{errorCode}}, message : \"{{message}}\"", + "success": "Project `{{projectName}}` successfully deleted" + }, + "map": { + "title": "Map Project `{{projectName}}` to a PDP", + "form": { + "pdp": "PDP" + }, + "action": { + "map": "Map", + "cancel": "Cancel" + }, + "check": { + "pdp": { + "required": "PDP is required" + } + }, + "error": "Unable to map Project `{{projectName}}` to a PDP `{{pdpName}}`", + "success": "Project `{{projectName}}` successfully mapped to a PDP `{{pdpName}}`" + }, + "unmap": { + "title": "Unmap Project and PDP", + "content": "Are you sure you want to unmap Project `{{projectName}}` / PDP `{{pdpName}}` ?", + "action": { + "unmap": "Unmap", + "cancel": "Cancel" + }, + "error": "Unable to unmap Project `{{projectName}}` / PDP `{{pdpName}}`", + "success": "Project `{{projectName}}` / PDP `{{pdpName}}` successfully unmapped" + } + }, + "pdp": { + "title": "PDPs", + "edit" : { + "title": "Pdp `{{pdpName}}` configuration", + "update" : "- update", + "basic" : { + "title" : "Basic Information", + "form": { + "id": "Id", + "name": "Name", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Update" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to update PDP `{{pdpName}}`", + "success": "PDP `{{pdpName}}` successfully updated" + }, + "policy": { + "title" : "Policies" + } + }, + "list": { + "search": { + "placeholder": "Search PDPs", + "reset": "Reset" + }, + "table": { + "name": "Name", + "security_pipeline":{ + "number" : "Number of Securities" + }, + "project": "Project", + "loading": { + "pdp": "Loading PDPs", + "project": "Loading Project" + }, + "mapping" :{ + "map": "Is not mapped" + }, + "notFound": "There is no PDPs" + }, + "action": { + "title": "Actions", + "detail": "Consult", + "configure": "Configure", + "rule": "Rules", + "delete": "Delete", + "add": "Add PDP", + "edit":"Editer" + }, + "error": "Unable to retrieve PDPs" + }, + "add": { + "title": "Add new PDP", + "form": { + "name": "Name", + "policy": "Policy", + "description": "Description" + }, + "action": { + "create": "Create PDP", + "cancel": "Cancel" + }, + "check": { + "name": { + "required": "Name is required" + }, + "policy": { + "required": "Policy is required" + } + }, + "error": "Unable to create PDP `{{pdpName}}`", + "success": "PDP `{{pdpName}}` successfully created" + }, + "remove": { + "title": "Delete PDP", + "content": "Are you sure you want to delete `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete PDP `{{pdpName}}`", + "success": "PDP `{{pdpName}}` successfully deleted" + }, + "configure": { + "title": "PDP `{{pdpName}}` configuration", + "action": { + "back": "Back to PDPs" + }, + "subject": { + "panelTitle": "Subjects configuration", + "title": "Subjects", + "add": { + "title": "Add new Subject", + "form": { + "name": "Name", + "domain": "Domain", + "enabled": "Enabled", + "project": "Project", + "password": "Password", + "description": "Description" + }, + "action": { + "cancel": "Cancel", + "add": "Add Subject" + }, + "check": { + "name": { + "required": "Name is required" + }, + "domain": { + "required": "Domain is required" + }, + "project": { + "required": "Project is required" + }, + "password": { + "required": "Password is required" + } + }, + "error": "Unable to add Subject `{{subjectName}}`", + "success": "Subject `{{subjectName}}` successfully added" + }, + "remove": { + "title": "Delete Subject", + "content": "Are you sure you want to delete `{{subjectName}}` subject of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Subject `{{subjectName}}`", + "success": "Subject `{{subjectName}}` successfully deleted" + }, + "category": { + "title": "Categories", + "add": { + "title": "Add new Category", + "form": { + "name": "Name" + }, + "action": { + "cancel": "Cancel", + "add": "Add Category" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to add Subject Category `{{categoryName}}`", + "success": "Subject Category `{{categoryName}}` successfully added" + }, + "remove": { + "title": "Delete Category", + "content": "Are you sure you want to delete `{{categoryName}}` subject category of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Subject Category `{{categoryName}}`", + "success": "Subject Category `{{categoryName}}` successfully deleted" + } + }, + "categoryValue": { + "title": "Values", + "add": { + "title": "Add new Value", + "form": { + "value": "Value" + }, + "action": { + "cancel": "Cancel", + "add": "Add Value" + }, + "check": { + "value": { + "required": "Value is required" + } + }, + "error": "Unable to add Subject Category Value`{{valueName}}`", + "success": "Subject Category Value `{{valueName}}` successfully added" + }, + "remove": { + "title": "Delete Value", + "content": "Are you sure you want to delete `{{valueName}}` subject category value of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Subject Category Value `{{valueName}}`", + "success": "Subject Category Value `{{valueName}}` successfully deleted" + } + }, + "assignment": { + "title": "Subject Assignments", + "action": { + "assign": "Assign", + "unassign": "Unassign" + }, + "list": { + "notFound": "There is no assignments" + }, + "add": { + "error": "Unable to assign Subject `{{subjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}`", + "success": "Subject `{{subjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}` assignment successfully done" + }, + "remove": { + "error": "Unable to unassign Subject `{{subjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}`", + "success": "Subject `{{subjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}` unassignment successfully done" + } + } + }, + "object": { + "panelTitle": "Objects configuration", + "title": "Objects", + "add": { + "title": "Add new Object", + "form": { + "name": "Name", + "image": "Image", + "flavor": "Flavor" + }, + "action": { + "cancel": "Cancel", + "add": "Add Object" + }, + "check": { + "name": { + "required": "Name is required" + }, + "image": { + "required": "Image is required" + }, + "flavor": { + "required": "Flavor is required" + } + }, + "error": "Unable to add Object `{{objectName}}`", + "success": "Object `{{objectName}}` successfully added" + }, + "remove": { + "title": "Delete Object", + "content": "Are you sure you want to delete `{{objectName}}` object of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Object `{{objectName}}`", + "success": "Object `{{objectName}}` successfully deleted" + }, + "category": { + "title": "Categories", + "add": { + "title": "Add new Category", + "form": { + "name": "Name" + }, + "action": { + "cancel": "Cancel", + "add": "Add Category" + }, + "check": { + "name": { + "required": "Name is required" + } + }, + "error": "Unable to add Object Category `{{categoryName}}`", + "success": "Object Category `{{categoryName}}` successfully added" + }, + "remove": { + "title": "Delete Category", + "content": "Are you sure you want to delete `{{categoryName}}` object category of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Object Category `{{categoryName}}`", + "success": "Object Category `{{categoryName}}` successfully deleted" + } + }, + "categoryValue": { + "title": "Values", + "add": { + "title": "Add new Value", + "form": { + "value": "Value" + }, + "action": { + "cancel": "Cancel", + "add": "Add Value" + }, + "check": { + "value": { + "required": "Value is required" + } + }, + "error": "Unable to add Object Category Value`{{valueName}}`", + "success": "Object Category Value `{{valueName}}` successfully added" + }, + "remove": { + "title": "Delete Value", + "content": "Are you sure you want to delete `{{valueName}}` object category value of `{{pdpName}}` PDP ?", + "action": { + "cancel": "Cancel", + "delete": "Delete" + }, + "error": "Unable to delete Object Category Value `{{valueName}}`", + "success": "Object Category Value `{{valueName}}` successfully deleted" + } + }, + "assignment": { + "title": "Object Assignments", + "action": { + "assign": "Assign", + "unassign": "Unassign" + }, + "list": { + "notFound": "There is no assignments" + }, + "add": { + "error": "Unable to assign Object `{{objectName}}` / Category `{{categoryName}}` / Value `{{valueName}}`", + "success": "Object `{{objectName}}` / Category `{{categoryName}}` / Value `{{valueName}}` assignment successfully done" + }, + "remove": { + "error": "Unable to unassign Object `{{ObjectName}}` / Category `{{categoryName}}` / Value `{{valueName}}`", + "success": "Object `{{objectName}}` / Category `{{categoryName}}` / Value `{{valueName}}` unassignment successfully done" + } + } + } + }, + "rule": { + "title": "PDP `{{pdpName}}` rules", + "list": { + "table": { + "subject": "Subjects", + "object": "Objects", + "notFound": "There is no Rules" + }, + "action": { + "title": "Actions", + "add": "Add Rule", + "delete": "Delete Rule" + } + }, + "add": { + "title": "Add new Rule", + "action": { + "create": "Create Rule", + "cancel": "Cancel" + }, + "form": { + "subject": { + "subject": "Subjects", + "category": "Categories", + "categoryValue": "Values", + "action": { + "add": "Add", + "delete": "Delete" + } + }, + "object": { + "object": "Objects", + "category": "Categories", + "categoryValue": "Values", + "action": { + "add": "Add", + "delete": "Delete" + } + } + }, + "success": "Rule successfully created", + "error": "Unable to create Rule" + }, + "delete": { + "title": "Delete Rule", + "content": "Are you sure you want to delete rule `{{ruleJson}}` of `{{pdpName}}` PDP ?", + "action": { + "delete": "Delete Rule", + "cancel": "Cancel" + }, + "error": "Unable to delete Rule `{{ruleJson}}`", + "success": "Rule `{{ruleJson}}` successfully deleted" + }, + "action": { + "back": "Back to PDPs" + } + } + } + } +} diff --git a/moonv4/moon_gui/delivery/assets/i18n/fr.json b/moonv4/moon_gui/delivery/assets/i18n/fr.json new file mode 100755 index 00000000..957fbac5 --- /dev/null +++ b/moonv4/moon_gui/delivery/assets/i18n/fr.json @@ -0,0 +1,1266 @@ +{ + "moon": { + "global": { + "applicationName": "Moon", + "404": "Page non trouvée", + "error": "Une erreur globale est survenue: {{stacktrace}}" + }, + "compatibility": { + "label": "Compatibilité navigateurs Web", + "title": "Compatibilité avec les navigateurs existants", + "content": "Moon est compatible avec : ", + "close": "Fermer" + }, + "menu": { + "project": "Project", + "pdp": "PDP", + "logs": "Log", + "policy": "Politique", + "model": "Modèle" + }, + "login":{ + "title":"Connexion", + "titlePage" : "Page d'idenditifcation", + "username" : "Nom d'utilisateur", + "password" : "Mot de passe", + "login" : "Connexion", + "check": { + "username": { + "required": "Le nom d'utilisateur est requis" + }, + "password": { + "required": "Le mot de passe est requis" + } + }, + "error" : "Impossible de se connecter à Keystone, code d'erreur {{errorCode}}", + "success" : "Connexion établie, Bienvenue sur la GUI de Moon, \"La lune est au dessus des nuages\"" + }, + "logout": { + "title": "Déconnexion", + "success" : "Déconnxion réussie" + }, + "dashboard":{ + "content" : "Moon:Software-Defined Security Framework" + }, + "policy": { + "title": "Politiques", + "list" : { + "search": { + "placeholder": "Rechercher des Politiques", + "reset": "Effacer" + }, + "table" : { + "name":"Nom", + "genre" : "Genre", + "description": "Description", + "loading": { + "category" : "Chargement de la Catégorie" + }, + "notFound": "Il n'existe aucune Politique" + }, + "action": { + "title": "Actions", + "add": "Ajouter une Politique", + "detail": "Consulter", + "edit": "Editer", + "map" : "Associer une Politique à la PDP", + "unmap" : "Dissocier", + "delete": "Supprimer" + } + }, + "unmap": { + "title": "Dissociation de la Policy et de la PDP", + "content": "Voulez-vous dissocier la PDP `{{pdpName}}` et la Policy `{{policyName}}` ?", + "action": { + "unmap": "Dissocier", + "cancel": "Annuler" + }, + "error": "Impossible de dissocier la PDP `{{pdpName}}` et la Policy`{{policyName}}`", + "success": "La dissociation de la PDP `{{pdpName}}` et de la Policy `{{policyName}}` a été effectuée avec succès" + }, + "map":{ + "title": "Associer une Politique à la PDP `{{pdpName}}`", + "form" :{ + "list": "Liste des Politiques" + }, + "action": { + "create": "Associer une Politique", + "cancel": "Fermer", + "new": "Créer une Politique", + "list": "Associer une Politique existante", + "map": "Associer la Politique sélectionnée", + "delete" : "Supprimer la Politique sélectionnée" + }, + "check": { + "policy":{ + "required" : "La politique est requise" + } + }, + "error": "Impossible d'associer la Politique `{{policyName}}` à la PDP `{{pdpName}}`", + "success": "L'association dde la Politique `{{policyName}}` avec la PDP `{{pdpName}}` a été effectuée avec succès" + }, + "remove": { + "title": "Supprimer une Politique", + "content": { + "query": "Voulez-vous supprimer la Politique `{{policyName}}` ?" + }, + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Politique `{{policyName}}`", + "success": "La Politique `{{policyName}}` a été supprimée avec succès" + }, + "edit" : { + "title": "Configuration de la Politique `{{policyName}}`", + "update": "- mettre à jour", + "show": { + "open": "( voir )", + "close": "( fermer )" + }, + "basic" : { + "title" : "Informations de base", + "form": { + "id": "Id", + "name": "Nom", + "genre": "Genre", + "model": "Modèle", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Mettre à Jour" + }, + "check": { + "name": { + "required": "Le Nom est requis" + }, + "Genre": { + "required": "Le Genre est requis" + } + }, + "error": "Impossible de mettre à jour la Politique `{{policyName}}`", + "success": "Le Politique `{{policyName}}` a été mise à jour avec succès" + }, + "perimeter": { + "title" : "Périmètres" + }, + "data": { + "title" : "Données" + }, + "rules" : { + "title" : "Règles" + }, + "assignments": { + "title" : "Affectations" + } + }, + "add": { + "title": "Ajouter une nouvelle Politique", + "form": { + "name": "Nom", + "genre" : "Genre", + "model": "Modèles", + "description": "Description" + }, + "action": { + "create": "Créer la Politique", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "genre" : { + "required" :"Le Genre est requis" + }, + "model" : { + "required" :"Un Modèle est requis" + } + }, + "error": "Impossible de créer la Politique `{{policyName}}`", + "success": "La Politique `{{policyName}}` a été créée avec succès" + }, + "perimeter" :{ + "subject" : { + "title" : "Liste des Sujets associées", + "delete": { + "error" : "Impossible de supprimer le Sujet : {{subjectName}}, la raison : {{reason}}", + "success": "Sujet `{{subjectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Element Sujet" + }, + "notFound": "Il n'existe aucun Sujet" + }, + "object" : { + "title" : "Liste des Objets associées", + "delete": { + "error" : "Impossible de supprimer l'Objet : {{objectName}}, la raison : {{reason}}", + "success": "Objet `{{objectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Element Objet" + }, + "notFound": "Il n'existe aucun Objet" + }, + "action" : { + "title" : "Liste des Actions associées", + "delete": { + "error" : "Impossible de supprimer l'Action : {{actionName}}, la raison : {{reason}}", + "success": "Action `{{actionName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Element Action" + }, + "notFound": "Il n'existe aucune Action" + }, + "table": { + "id" : "Id", + "name" : "Nom", + "description" : "Description", + "email" : "Email", + "partner":{ + "id" : "Id du Partenaire" + }, + "action": { + "title": "Actions", + "delete": "Supprimer", + "update": "Mettre à jour" + } + }, + "edit": { + "name" : "Nom", + "description" : "Description", + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "action": { + "list": "Associer un Element existante", + "new": "Créer une nouvelle Element", + "create":"Créer l'Element", + "map":"Asscoier l'Element selectionnée", + "delete": "Supprimer" + }, + "create": { + "error": "Impossible de créer l'Element `{{name}}`", + "success": "L'Element `{{name}}` a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Element `{{name}}`", + "success": "L'Element `{{name}}` a été supprimée avec succès" + } + } + }, + "data" :{ + "subject" : { + "title" : "Liste des Data Sujets associées", + "delete": { + "error" : "Impossible de supprimer la Data Sujet : {{subjectName}}, la raison : {{reason}}", + "success": "Data Sujet `{{subjectName}}` a été supprimée avec succès" + }, + "add": { + "title": "Ajouter une Data Sujet" + }, + "notFound": "Il n'existe aucune Data Sujet" + }, + "object" : { + "title" : "Liste des Data Objets associées", + "delete": { + "error" : "Impossible de supprimer la Data Objet : {{objectName}}, la raison : {{reason}}", + "success": "Data Objet `{{objectName}}` a été supprimée avec succès" + }, + "add": { + "title": "Ajouter un Data Objet" + }, + "notFound": "Il n'existe aucun Data Objet" + }, + "action" : { + "title" : "Liste des Data Actions associées", + "delete": { + "error" : "Impossible de supprimer la Data Action : {{actionName}}, la raison : {{reason}}", + "success": "Data Action `{{actionName}}` a été supprimée avec succès" + }, + "add": { + "title": "Ajouter une Data Action" + }, + "notFound": "Il n'existe aucune Data Action" + }, + "table": { + "category" : { + "id" : "Id de la Catégorie", + "name" : "Nom de la Catégorie" + }, + "name" : "Nom", + "description" : "Description", + "action": { + "title": "Actions", + "delete": "Supprimer", + "update": "Mettre à jour" + }, + "loading": { + "category" : "Loading Catégorie" + } + }, + "edit": { + "name" : "Nom", + "description" : "Description", + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "action": { + "list": "Associer un Element existante", + "new": "Créer une nouvelle Element", + "create":"Créer l'Element", + "map":"Asscoier l'Element selectionnée", + "delete": "Supprimer" + }, + "create": { + "error": "Impossible de créer l'Element `{{name}}`", + "success": "L'Element `{{name}}` a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Element `{{name}}`", + "success": "L'Element `{{name}}` a été supprimée avec succès" + } + } + }, + "rules": { + "title": "Règles", + "list": { + "search": { + "placeholder": "Rechercher des Règles", + "reset": "Effacer" + }, + "table": { + "id" : "Id", + "metaRule": "Meta Règle", + "description": "Description", + "enabled": "Enabled", + "rule": "Règle", + "notFound": "Il n'existe aucune Règle", + "loading": { + "metaRule" : "Chargement de la Meta Règle" + } + }, + "action": { + "title": "Actions", + "add": "Ajouter une Règle", + "detail": "Consulter", + "edit": "Editer", + "delete": "Supprimer" + }, + "error": "Impossible de récupérer la liste des Règles" + } + }, + "assignments" :{ + "subject" : { + "title" : "Liste des Affectations Sujets associées", + "delete": { + "error" : "Impossible de supprimer l'Affectations Sujet : {{subjectName}}, la raison : {{reason}}", + "success": "Affectations Sujet `{{subjectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Affectations Sujet" + }, + "notFound": "Il n'existe aucune Affectations Sujet" + }, + "object" : { + "title" : "Liste des Affectations Objets associées", + "delete": { + "error" : "Impossible de supprimer l'Affectations Objet : {{objectName}}, la raison : {{reason}}", + "success": "Affectations Objet `{{objectName}}` a été supprimée avec succès" + }, + "add": { + "title": "Ajouter une Affectations Objet" + }, + "notFound": "Il n'existe aucune Affectations Objet" + }, + "action" : { + "title" : "Liste des Affectations Actions associées", + "delete": { + "error" : "Impossible de supprimer l'Affectations Action : {{actionName}}, la raison : {{reason}}", + "success": "Affectations Action `{{actionName}}` a été supprimée avec succès" + }, + "add": { + "title": "Ajouter une Affectations Action" + }, + "notFound": "Il n'existe aucune Affectations Action" + }, + "table": { + "action": { + "title": "Actions", + "delete": "Supprimer", + "update": "Mettre à jour" + }, + "perimeter": { + "name": "Nom du Périmètre" + }, + "data":{ + "name" : "Nom des Data" + }, + "category": { + "name" : "Nom de la Catégorie" + }, + "loading": { + "category" : "Chargement de la Catégorie", + "perimeter": "Chargement du Périmètre", + "data": "Chargement des Données" + } + }, + "edit": { + "name" : "Nom", + "description" : "Description", + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "action": { + "list": "Associer une Affectations existante", + "new": "Créer une nouvelle Affectations", + "create":"Créer l'Affectations", + "map":"Asscoier l'Affectations selectionnée", + "delete": "Supprimer" + }, + "create": { + "error": "Impossible de créer l'Affectations `{{name}}`", + "success": "L'Affectations `{{name}}` a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer l'Affectations `{{name}}`", + "success": "L'Affectations `{{name}}` a été supprimée avec succès" + } + } + } + }, + "model":{ + "title": "Modèles", + "list": { + "search": { + "placeholder": "Rechercher des Modèles", + "reset": "Effacer" + }, + "table":{ + "name":"Nom", + "description": "Description", + "metaRules":{ + "number" : "Nombre de Meta Règles" + }, + "notFound": "Il n'existe aucun Modèle" + }, + "action": { + "title": "Actions", + "add": "Ajouter un modèle", + "detail": "Consulter", + "edit": "Editer", + "delete": "Supprimer" + }, + "error": "Impossible de récupérer la liste des Modèles" + }, + "edit" : { + "title": "Configuration du Modèle `{{modelName}}`", + "update": "- mettre à jour", + "basic" : { + "title" : "Informations de base", + "form": { + "id": "Id", + "name": "Nom", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Mettre à Jour" + }, + "check": { + "name": { + "required": "Le Nom est requis" + } + }, + "error": "Impossible de mettre à jour le Modèle `{{modelName}}`", + "success": "Le Modèle `{{modelName}}` a été mis à jour avec succès" + }, + "metarules": { + "title" : "Meta Règles" + } + }, + "view": { + "title": "Détail du Modèle `{{modelName}}`", + "name": "Name", + "id": "Id", + "description": "Description", + "action": { + "close": "Fermer" + } + }, + "remove": { + "title": "Supprimer un Modèle", + "content": { + "query": "Voulez-vous supprimer le Modèle `{{modelName}}` ?" + }, + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer le Modèle `{{modelName}}`", + "success": "Le Modèle `{{modelName}}` a été supprimé avec succès" + }, + "metarules" :{ + "title" : "List des Meta Règles", + "table":{ + "name":"Nom", + "description": "Description", + "metadata": { + "subject" : { + "number" : "Nombre de Catégories Sujet" + }, + "object" : { + "number" : "Nombre de Catégories Objet" + }, + "action" : { + "number" : "Nombre de Catégories Action" + } + }, + "notFound": "Il n'existe aucune Meta Règles" + }, + "edit" : { + "title" : "Configuration de la Meta Règle `{{metaRuleName}}`", + "update": "- mettre à jour", + "basic" : { + "title" : "Informations de base", + "form": { + "id": "Id", + "name": "Nom", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Mettre à Jour" + }, + "check": { + "name": { + "required": "Le Nom est requis" + } + }, + "error": "Impossible de mettre à jour la Meta Règle `{{metaRuleName}}`", + "success": "La Meta Règle `{{metaRuleName}}` a été mis à jour avec succès" + } + }, + "update":{ + "error": "Impossible de mettre à jour la Meta Règle `{{metaRuleName}}`", + "success": "La Meta Règle `{{metaRuleName}}` a été mis à jour avec succès" + }, + "action": { + "title": "Actions", + "edit": "Editer", + "remove": "Enlever", + "settings" : "Paramètres", + "add": "Ajouter", + "detail": { + "open": "Consulter", + "close": "Fermer" + } + }, + "add":{ + "title": "Ajouter une nouvelle Meta Règle", + "form": { + "name": "Nom", + "description": "Description" + }, + "action": { + "create": "Ajouter la Meta Règle", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "error": "Impossible de créer la Meta Règle `{{metaRuleName}}`", + "success": "La Meta Règle `{{metaRuleName}}` a été créée avec succès" + }, + "map":{ + "title": "Ajouter une Meta Règle", + "form" :{ + "list": "Liste des Meta Règles" + }, + "action": { + "create": "Ajouter une nouvelle Meta Règle", + "cancel": "Fermer", + "new": "Ajouter une Meta Règle", + "list": "Ajouter une Meta Règle existante", + "add": "Ajouter la Meta Règle sélectionnée", + "delete" : "Supprimer la Meta Règle sélectionnée" + }, + "error": "Impossible d'associer le Modèle `{{modelName}}` à la Meta Règle `{{metaRuleName}}`", + "success": "L'association du Modèle `{{modelName}}` avec la Meta Règle `{{metaRuleName}}` a été effectuée avec succès" + }, + "unmap": { + "title": "Enlever de la Meta Règle du Modèle", + "content": "Voulez-vous enlever le Modèle `{{modelName}}` de la Meta Règle `{{metaRuleName}}` ?", + "action": { + "unmap": "Enlever", + "cancel": "Annuler" + }, + "error": "Impossible d'enlever le Modèle `{{modelName}}` de la Meta Règle `{{metaRuleName}}`", + "success": "La dissociation du Modèle `{{modelName}}` de la Meta Règle `{{metaRuleName}}` a été effectuée avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Meta Rule `{{metaRuleName}}`", + "success": "La Meta Rule `{{metaRuleName}}` a été supprimée avec succès" + } + }, + "metadata" :{ + "subject" : { + "title" : "Liste des Catégories Sujet associées", + "delete": { + "error" : "Impossible de supprimer le Sujet : {{subjectName}}, la raison : {{reason}}", + "success": "Sujet `{{subjectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Catégorie Sujet" + }, + "notFound": "Il n'existe aucun Sujet" + }, + "object" : { + "title" : "Liste des Catégories Objet associées", + "delete": { + "error" : "Impossible de supprimer l'Objet : {{objectName}}, la raison : {{reason}}", + "success": "Objet `{{objectName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Catégorie Objet" + }, + "notFound": "Il n'existe aucun Objet" + }, + "action" : { + "title" : "Liste des Catégories Action associées", + "remove": "Enlever", + "delete": { + "error" : "Impossible de supprimer l'Action : {{actionName}}, la raison : {{reason}}", + "success": "Action `{{actionName}}` a été supprimé avec succès" + }, + "add": { + "title": "Ajouter une Catégorie Action" + }, + "notFound": "Il n'existe aucune Action" + }, + "table": { + "id" : "Id", + "name" : "Nom", + "description" : "Description", + "action": { + "title": "Actions", + "delete": "Supprimer", + "update": "Mettre à jour" + } + }, + "edit": { + "name" : "Nom", + "description" : "Description", + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "action": { + "list": "Ajouter une Catégorie existante", + "new": "Ajouter une nouvelle Catégorie", + "create":"Ajouter la Catégorie", + "add":"Ajouter la Catégorie selectionnée", + "delete": "Supprimer" + }, + "create": { + "error": "Impossible de créer la Catégorie `{{name}}`", + "success": "La Catégorie `{{name}}` a été créé avec succès" + }, + "delete": { + "error": "Impossible de supprimer la Catégorie `{{name}}`", + "success": "La Catégorie `{{name}}` a été supprimée avec succès" + } + } + }, + "add":{ + "title": "Ajouter un nouveau Model", + "form": { + "name": "Nom", + "description": "Description" + }, + "action": { + "create": "Créer le Modèle", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "error": "Impossible de créer le Modèle `{{modelName}}`", + "success": "Le Modèle `{{modelName}}` a été créé avec succès" + } + }, + "project": { + "title": "Projects", + "list": { + "search": { + "placeholder": "Rechercher des Projects", + "reset": "Effacer" + }, + "table": { + "name": "Nom", + "domain": "Domaine", + "managed": "Supervisé", + "enabled": "Activé", + "description": "Description", + "mapping": "PDP", + "loading": { + "project": "Chargement des Projects", + "pdp": "Chargement du PDP" + }, + "notFound": "Il n'existe aucun Project" + }, + "action": { + "title": "Actions", + "detail": "Consulter", + "delete": "Supprimer", + "add": "Ajouter un Project", + "map": "Associer à un PDP", + "unmap": "Dissocier" + }, + "error": "Impossible de récupérer la liste des Projects" + }, + "view": { + "title": "Détail du Project `{{projectName}}`", + "action": { + "close": "Fermer" + }, + "subject": { + "title": "Sujets", + "name": "Nom", + "mail": "Email", + "domain": "Domaine", + "enabled": "Activé", + "error": "Impossible de récupérer la liste des Sujets" + }, + "object": { + "title": "Objets", + "category": "Catégorie", + "description": "Description", + "enabled": "Activé", + "name": "Nom", + "error": "Impossible de récupérer la liste des Objets", + "loading": "Chargement des Objets", + "notFound": "Il n'existe aucun Objet" + }, + "role": { + "title": "Roles", + "category": "Catégorie", + "value": "Valeur", + "description": "Description", + "assigned": "Affecté", + "enabled": "Activé", + "error": "Impossible de récupérer la liste des Roles", + "loading": "Chargement des Roles", + "notFound": "Il n'existe aucun Role" + }, + "roleAssignment": { + "title": "Affectation des roles", + "category": "Catégorie", + "attributes": "Attributs", + "description": "Description", + "error": "impossible de récupérer la liste des affectations", + "loading": "Chargement des Affectations", + "notFound": "Il n'existe aucune Affectation" + }, + "group": { + "title": "Groupes", + "category": "Catégorie", + "value": "Valeur", + "description": "Description", + "assigned": "Affecté", + "enabled": "Activé", + "error": "Impossible de récupérer la liste des Groupes", + "loading": "Chargement des Groupes", + "notFound": "Il n'existe aucun Groupe" + }, + "groupAssignment": { + "title": "Affectation des groupes", + "category": "Catégorie", + "attributes": "Attributs", + "description": "Description", + "error": "impossible de récupérer la liste des affectations", + "loading": "Chargement des Affectations", + "notFound": "Il n'existe aucune Affectation" + } + }, + "add": { + "title": "Ajouter un nouveau Project", + "form": { + "name": "Nom", + "description": "Description", + "enabled": "Activé", + "domain": "Domaine" + }, + "action": { + "create": "Créer le Project", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "domain": { + "required": "Le domaine est requis" + } + }, + "error": "Impossible de créer le Project `{{projectName}}`", + "success": "Le Project `{{projectName}}` a été créé avec succès" + }, + "remove": { + "title": "Supprimer un Project", + "content": { + "query": "Voulez-vous supprimer le Project `{{projectName}}` ?", + "isNotMapped": "Ce Project est associé avec aucune PDP.", + "isMapped": "Ce project est associé avec le PDP `{{pdpName}}`, le supprimer va supprimer le mapping associé" + }, + "mapping":{ + "remove":{ + "error": "Impossible de supprimer la relation avec `{{pdpName}}`" + } + }, + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer le Project `{{projectName}}`", + "success": "Le Project `{{projectName}}` a été supprimé avec succès" + }, + "map": { + "title": "Associé le Project `{{projectName}}` avec une PDP", + "form": { + "pdp": "PDP" + }, + "action": { + "map": "Associer", + "cancel": "Annuler" + }, + "check": { + "pdp": { + "required": "L'PDP est requise" + } + }, + "error": "Impossible d'associer le Project `{{projectName}}` avec la PDP `{{pdpName}}`", + "success": "L'association du Project `{{projectName}}` avec la PDP `{{pdpName}}` a été effectué avec succès" + }, + "unmap": { + "title": "Dissociation Project et PDP", + "content": "Voulez-vous dissocier le Project `{{projectName}}` et la PDP `{{pdpName}}` ?", + "action": { + "unmap": "Dissocier", + "cancel": "Annuler" + }, + "error": "Impossible de dissocier le Project `{{projectName}}` et la PDP `{{pdpName}}`", + "success": "La dissociation du Project `{{projectName}}` et de la PDP `{{pdpName}}` a été effectuée avec succès" + } + }, + "pdp": { + "title": "PDPs", + "edit" : { + "title": "configuration du PDP `{{pdpName}}` ", + "update" : "- Mettre à jour", + "basic" : { + "title" : "Information de base", + "form": { + "id": "Id", + "name": "Nom", + "description": "Description" + }, + "action": { + "init": "Init", + "update": "Mettre à jour" + }, + "check": { + "name": { + "required": "Le Nom est requis" + } + }, + "error": "Impossible de mettre à jour la PDP `{{pdpName}}`", + "success": "La PDP `{{pdpName}}` a été mis à jour avec succès" + }, + "policy": { + "title" : "Politiques" + } + }, + "list": { + "search": { + "placeholder": "Rechercher des PDPs", + "reset": "Effacer" + }, + "table": { + "name": "Nom", + "security_pipeline":{ + "number" : "Nombre de Règles" + }, + "project": "Project", + "loading": { + "pdp": "Chargement des PDPs", + "project": "Chargement du Project" + }, + "mapping" :{ + "map": "n'est pas associé à un projet" + }, + "notFound": "Il n'existe aucune PDP" + }, + "action": { + "title": "Actions", + "detail": "Consulter", + "configure": "Configurer", + "rule": "Règles", + "delete": "Supprimer", + "add": "Ajouter une PDP", + "edit": "Editer" + }, + "error": "Impossible de récupérer la liste des PDPs" + }, + "add": { + "title": "Ajouter une nouvelle PDP", + "form": { + "name": "Nom", + "policy": "Règle", + "description": "Description" + }, + "action": { + "create": "Créer la PDP", + "cancel": "Annuler" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "policy": { + "required": "Une règle est requise" + } + }, + "error": "Impossible de créer la PDP `{{pdpName}}`", + "success": "La PDP `{{pdpName}}` a été créée avec succès" + }, + "remove": { + "title": "Supprimer une PDP", + "content": "Voulez-vous supprimer la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la PDP `{{pdpName}}`", + "success": "la PDP `{{pdpName}}` a été supprimé avec succès" + }, + "configure": { + "title": "Configuration de la PDP `{{pdpName}}`", + "action": { + "back": "Liste des PDPs" + }, + "subject": { + "panelTitle": "Configuration des Sujets", + "title": "Sujets", + "add": { + "title": "Ajouter un nouveau Sujet", + "form": { + "name": "Nom", + "domain": "Domaine", + "enabled": "Activé", + "project": "Projet", + "password": "Mot de passe", + "description": "Description" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Sujet" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "domain": { + "required": "Le domaine est requis" + }, + "project": { + "required": "Le projet est requis" + }, + "password": { + "required": "Le mot de passe est requis" + } + }, + "error": "Impossible d'ajouter le Sujet `{{subjectName}}`", + "success": "Le Sujet `{{subjectName}}` a été ajouté avec succès" + }, + "remove": { + "title": "Supprimer un Sujet", + "content": "Voulez-vous supprimer le Sujet `{{subjectName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer le Sujet `{{subjectName}}`", + "success": "Le Sujet `{{subjectName}}` a été supprimé avec succès" + }, + "category": { + "title": "Catégories", + "add": { + "title": "Ajouter une nouvelle Catégorie", + "form": { + "name": "Nom" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Catégorie" + }, + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "error": "Impossible d'ajouter la Catégorie `{{categoryName}}`", + "success": "Catégorie `{{categoryName}}` ajoutée avec succès" + }, + "remove": { + "title": "Supprimer une Catégorie", + "content": "Voulez-vous supprimer la Catégorie `{{categoryName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Catégorie `{{categoryName}}`", + "success": "La Catégorie `{{categoryName}}` a été supprimée avec succès" + } + }, + "categoryValue": { + "title": "Valeurs", + "add": { + "title": "Ajouter une nouvelle Valeur", + "form": { + "value": "Valeur" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Valeur" + }, + "check": { + "value": { + "required": "La valeur est requise" + } + }, + "error": "Impossible d'ajouter la Valeur `{{valueName}}`", + "success": "Valeur `{{valueName}}` ajoutée avec succès" + }, + "remove": { + "title": "Supprimer une Valeur", + "content": "Voulez-vous supprimer la Valeur `{{valueName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Valeur `{{valueName}}`", + "success": "La Valeur `{{valueName}}` a été supprimée avec succès" + } + }, + "assignment": { + "title": "Affectation des Sujets", + "action": { + "assign": "Affecter", + "unassign": "Désaffecter" + }, + "list": { + "notFound": "Il n'existe aucune affectation" + }, + "add": { + "error": "Impossible de réaliser l'affectation Sujet `{{subjectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}`", + "success": "Affectation de Sujet `{{subjectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}` réalisée avec succès" + }, + "remove": { + "error": "Impossible de réaliser la désaffectation Sujet `{{subjectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}`", + "success": "Désaffectation de Sujet `{{subjectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}` réalisée avec succès" + } + } + }, + "object": { + "panelTitle": "Configuration des Objets", + "title": "Objets", + "add": { + "title": "Ajouter un nouvel Objet", + "form": { + "name": "Nom", + "image": "Image", + "flavor": "Type" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Objet" + }, + "check": { + "name": { + "required": "Le nom est requis" + }, + "image": { + "required": "L'image est requise" + }, + "flavor": { + "required": "Le type est requis" + } + }, + "error": "Impossible d'ajouter l'Objet `{{objectName}}`", + "success": "L'Objet `{{objectName}}` a été ajouté avec succès" + }, + "remove": { + "title": "Supprimer un Objet", + "content": "Voulez-vous supprimer l'Objet `{{objectName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer l'Objet `{{objectName}}`", + "success": "L'Objet `{{objectName}}` a été supprimé avec succès" + }, + "category": { + "title": "Catégories", + "add": { + "title": "Ajouter une nouvelle Catégorie", + "form": { + "name": "Nom" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Catégorie" + }, + "check": { + "name": { + "required": "Le nom est requis" + } + }, + "error": "Impossible d'ajouter la Catégorie `{{categoryName}}`", + "success": "Catégorie `{{categoryName}}` ajoutée avec succès" + }, + "remove": { + "title": "Supprimer une Catégorie", + "content": "Voulez-vous supprimer la Catégorie `{{categoryName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Catégorie `{{categoryName}}`", + "success": "La Catégorie `{{categoryName}}` a été supprimée avec succès" + } + }, + "categoryValue": { + "title": "Valeurs", + "add": { + "title": "Ajouter une nouvelle Valeur", + "form": { + "value": "Valeur" + }, + "action": { + "cancel": "Annuler", + "add": "Ajouter Valeur" + }, + "check": { + "value": { + "required": "La valeur est requise" + } + }, + "error": "Impossible d'ajouter la Valeur `{{valueName}}`", + "success": "Valeur `{{valueName}}` ajoutée avec succès" + }, + "remove": { + "title": "Supprimer une Valeur", + "content": "Voulez-vous supprimer la Valeur `{{valueName}}` de la PDP `{{pdpName}}` ?", + "action": { + "cancel": "Annuler", + "delete": "Supprimer" + }, + "error": "Impossible de supprimer la Valeur `{{valueName}}`", + "success": "La Valeur `{{valueName}}` a été supprimée avec succès" + } + }, + "assignment": { + "title": "Affectation des Objets", + "action": { + "assign": "Affecter", + "unassign": "Désaffecter" + }, + "list": { + "notFound": "Il n'existe aucune affectation" + }, + "add": { + "error": "Impossible de réaliser l'affectation Objet `{{objectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}`", + "success": "Affectation de Objet `{{objectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}` réalisée avec succès" + }, + "remove": { + "error": "Impossible de réaliser la désaffectation Objet `{{objectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}`", + "success": "Désaffectation de Objet `{{objectName}}` / Catégorie `{{categoryName}}` / Valeur `{{valueName}}` réalisée avec succès" + } + } + } + }, + "rule": { + "title": "Règles de la PDP `{{pdpName}}`", + "list": { + "table": { + "subject": "Sujets", + "object": "Objects", + "notFound": "Il n'existe aucune règle" + }, + "action": { + "title": "Actions", + "add": "Ajouter une règle", + "delete": "Supprimer une règle" + } + }, + "add": { + "title": "Ajouter une nouvelle Règle", + "action": { + "create": "Créer la Règle", + "cancel": "Annuler" + }, + "form": { + "subject": { + "subject": "Sujets", + "category": "Catégories", + "categoryValue": "Valeur", + "action": { + "add": "Ajouter", + "delete": "Supprimer" + } + }, + "object": { + "object": "Objets", + "category": "Catégories", + "categoryValue": "Valeurs", + "action": { + "add": "Ajouter", + "delete": "Supprimer" + } + } + }, + "success": "La règle a été créée avec succès", + "error": "Impossible de créer la règle" + }, + "delete": { + "title": "Supprime une Règle", + "content": "Voulez-vous supprimer la Valeur règle `{{ruleJson}}` de la PDP `{{pdpName}}` ?", + "action": { + "delete": "Supprimer la Règle", + "cancel": "Annuler" + }, + "error": "Impossible de supprimer la règle `{{ruleJson}}`", + "success": "La règle `{{ruleJson}}` a été supprimée avec succès" + }, + "action": { + "back": "Liste des PDPs" + } + } + } + } +} diff --git a/moonv4/moon_gui/delivery/assets/img/ajax-loader.gif b/moonv4/moon_gui/delivery/assets/img/ajax-loader.gif new file mode 100755 index 00000000..d0bce154 Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/img/ajax-loader.gif differ diff --git a/moonv4/moon_gui/delivery/assets/img/ajax-waiting.gif b/moonv4/moon_gui/delivery/assets/img/ajax-waiting.gif new file mode 100755 index 00000000..d84f6537 Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/img/ajax-waiting.gif differ diff --git a/moonv4/moon_gui/delivery/assets/img/arrow-link.gif b/moonv4/moon_gui/delivery/assets/img/arrow-link.gif new file mode 100755 index 00000000..ca17f44b Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/img/arrow-link.gif differ diff --git a/moonv4/moon_gui/delivery/assets/img/favicon.ico b/moonv4/moon_gui/delivery/assets/img/favicon.ico new file mode 100755 index 00000000..a7910bf5 Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/img/favicon.ico differ diff --git a/moonv4/moon_gui/delivery/assets/img/logo-openstack.png b/moonv4/moon_gui/delivery/assets/img/logo-openstack.png new file mode 100755 index 00000000..60ab0e1e Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/img/logo-openstack.png differ diff --git a/moonv4/moon_gui/delivery/assets/img/logo-orange.gif b/moonv4/moon_gui/delivery/assets/img/logo-orange.gif new file mode 100755 index 00000000..9c612291 Binary files /dev/null and b/moonv4/moon_gui/delivery/assets/img/logo-orange.gif differ diff --git a/moonv4/moon_gui/delivery/html/authentication/authentication.tpl.html b/moonv4/moon_gui/delivery/html/authentication/authentication.tpl.html new file mode 100644 index 00000000..d942d8e8 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/authentication/authentication.tpl.html @@ -0,0 +1 @@ +

Login

Username is required
Password is required
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/common/404/404.tpl.html b/moonv4/moon_gui/delivery/html/common/404/404.tpl.html new file mode 100644 index 00000000..f03a2e98 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/common/404/404.tpl.html @@ -0,0 +1 @@ +
Not found!
Go Projects ?
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html b/moonv4/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html new file mode 100644 index 00000000..7a39554e --- /dev/null +++ b/moonv4/moon_gui/delivery/html/common/compatibility/compatibility.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/common/footer/footer.tpl.html b/moonv4/moon_gui/delivery/html/common/footer/footer.tpl.html new file mode 100644 index 00000000..6c01bd92 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/common/footer/footer.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/common/header/header.tpl.html b/moonv4/moon_gui/delivery/html/common/header/header.tpl.html new file mode 100644 index 00000000..ecfc522e --- /dev/null +++ b/moonv4/moon_gui/delivery/html/common/header/header.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/common/loader/loader.tpl.html b/moonv4/moon_gui/delivery/html/common/loader/loader.tpl.html new file mode 100644 index 00000000..dc52e911 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/common/loader/loader.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/common/waiting/waiting.tpl.html b/moonv4/moon_gui/delivery/html/common/waiting/waiting.tpl.html new file mode 100644 index 00000000..eca2ae9e --- /dev/null +++ b/moonv4/moon_gui/delivery/html/common/waiting/waiting.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/dashboard/dashboard.tpl.html b/moonv4/moon_gui/delivery/html/dashboard/dashboard.tpl.html new file mode 100644 index 00000000..995c8910 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/dashboard/dashboard.tpl.html @@ -0,0 +1 @@ +

Moon:Software-Defined Security Framework

ET
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/logs/logs.tpl.html b/moonv4/moon_gui/delivery/html/logs/logs.tpl.html new file mode 100644 index 00000000..bb6dd686 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/logs/logs.tpl.html @@ -0,0 +1 @@ +
Logs
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/action/model-add.tpl.html b/moonv4/moon_gui/delivery/html/model/action/model-add.tpl.html new file mode 100644 index 00000000..5741b537 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/action/model-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/action/model-delete.tpl.html b/moonv4/moon_gui/delivery/html/model/action/model-delete.tpl.html new file mode 100644 index 00000000..79e4aa0d --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/action/model-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/action/model-view.tpl.html b/moonv4/moon_gui/delivery/html/model/action/model-view.tpl.html new file mode 100644 index 00000000..46673c0a --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/action/model-view.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html new file mode 100644 index 00000000..7d53a991 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-edit.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html new file mode 100644 index 00000000..c1d7e242 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/metadata/metadata-list.tpl.html @@ -0,0 +1,82 @@ +

List of associated Subject Categories

IdNameDescription
Remove
There is no Subjects

Add a Subject Category

List associated of Object Categories

IdNameDescription
Remove
There is no Objects

Add an Object Category

List associated of Action Categories

IdNameDescription
Remove
There is no Actions

Add an Action Category

.
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html new file mode 100644 index 00000000..8593236d --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-add.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html new file mode 100644 index 00000000..0170fc2e --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-map.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html new file mode 100644 index 00000000..76e1e486 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html new file mode 100644 index 00000000..3a171600 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit-basic.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html new file mode 100644 index 00000000..fe37cc90 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/metarules/action/metarules-edit.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html new file mode 100644 index 00000000..37d77cc3 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/metarules/metarules-list.tpl.html @@ -0,0 +1 @@ +

List of Meta Rules

Name
Description
Number of Subjects
Number of Subjects
Number of Actions
Actions
There is no Meta Rules
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html new file mode 100644 index 00000000..a645b1ee --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/model-edit-basic.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/edit/model-edit.tpl.html b/moonv4/moon_gui/delivery/html/model/edit/model-edit.tpl.html new file mode 100644 index 00000000..448871d3 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/edit/model-edit.tpl.html @@ -0,0 +1,4 @@ +

Edit

Basic Information Update
Id
Name
Description
Meta Rule
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/model/model-list.tpl.html b/moonv4/moon_gui/delivery/html/model/model-list.tpl.html new file mode 100644 index 00000000..138a66b7 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/model/model-list.tpl.html @@ -0,0 +1,6 @@ +
 
 
 
Name
Description
Number of Meta Rules
Actions
There is no Models
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html b/moonv4/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html new file mode 100644 index 00000000..e372a8c3 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/pdp/action/pdp-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html b/moonv4/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html new file mode 100644 index 00000000..2c8a5f34 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/pdp/action/pdp-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html b/moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html new file mode 100644 index 00000000..e15e27e0 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit-basic.tpl.html @@ -0,0 +1 @@ +
Name is required
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html b/moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html new file mode 100644 index 00000000..b231c0d5 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/pdp/edit/pdp-edit.tpl.html @@ -0,0 +1 @@ +

Edit

Basic Information Update

Id
Name
Description

Policies

\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/pdp/pdp-list.tpl.html b/moonv4/moon_gui/delivery/html/pdp/pdp-list.tpl.html new file mode 100644 index 00000000..31d1aae0 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/pdp/pdp-list.tpl.html @@ -0,0 +1 @@ +
 
 
 
Name
Number of Securities
Project
Actions
There is no PDP
Loading Project
Is not mapped
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html b/moonv4/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html new file mode 100644 index 00000000..9d115c18 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/action/mapping/policy-map.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html b/moonv4/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html new file mode 100644 index 00000000..3892782d --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/action/mapping/policy-unmap.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/action/policy-add.tpl.html b/moonv4/moon_gui/delivery/html/policy/action/policy-add.tpl.html new file mode 100644 index 00000000..e1220479 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/action/policy-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/action/policy-delete.tpl.html b/moonv4/moon_gui/delivery/html/policy/action/policy-delete.tpl.html new file mode 100644 index 00000000..d2c679e3 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/action/policy-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html b/moonv4/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html new file mode 100644 index 00000000..66fcaf73 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/edit/parameter/assignments/assignments-list.tpl.html @@ -0,0 +1 @@ +

List of associated Subjects

Perimeter nameCategory nameData name
Loading
Loading
,
There is no Subjects

Add a Subject Category

List associated of Objects

Perimeter nameCategory nameData name
Loading
Loading
,
There is no Objects

Add an Object Category

List associated of Actions

Perimeter nameCategory nameData name
Loading
Loading
,
There is no Actions

Add an Action Category

.
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html b/moonv4/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html new file mode 100644 index 00000000..a4619f2a --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/edit/parameter/data/data-list.tpl.html @@ -0,0 +1,113 @@ +

List of associated Subjects

NameDescriptionCategory
Loading
There is no Subjects

Add a Subject Category

List associated of Objects

NameDescriptionCategory
Loading
There is no Objects

Add an Object Category

List associated of Actions

NameDescriptionCategory
Loading
There is no Actions

Add an Action Category

.
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html b/moonv4/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html new file mode 100644 index 00000000..a137685a --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/edit/parameter/perimeter/perimeter-list.tpl.html @@ -0,0 +1,114 @@ +

List of associated Subjects

IdNameDescriptionEmail
There is no Subjects

Add a Subject Category

List associated of Objects

IdNameDescription
There is no Objects

Add an Object Category

List associated of Actions

IdNameDescription
There is no Actions

Add an Action Category

.
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html b/moonv4/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html new file mode 100644 index 00000000..b4f8da0a --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/edit/parameter/rules/rules-list.tpl.html @@ -0,0 +1 @@ +
Id
Meta Rule
Enabled
Rule
There is no Rules
Loading Loading ,
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html b/moonv4/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html new file mode 100644 index 00000000..23f760d4 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/edit/policy-edit-basic.tpl.html @@ -0,0 +1 @@ +
Name is required
{{$select.selected.name}}
{{model.name}}
Model is required
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html b/moonv4/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html new file mode 100644 index 00000000..38b308b0 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/edit/policy-edit.tpl.html @@ -0,0 +1,13 @@ +

Edit

Basic Information Update
Id
Name
Genre
Model
Description
Perimeters Show Show
Assignments Show Close
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/policy-list.tpl.html b/moonv4/moon_gui/delivery/html/policy/policy-list.tpl.html new file mode 100644 index 00000000..2e8a981c --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/policy-list.tpl.html @@ -0,0 +1 @@ +
 
 
 
Name
Genre
Description
Actions
There is no policy
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html b/moonv4/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html new file mode 100644 index 00000000..2e18a1b5 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/policy/policy-mapped-list.tpl.html @@ -0,0 +1 @@ +
Name
Genre
Description
Actions
There is no policy
Unmap
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html b/moonv4/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html new file mode 100644 index 00000000..dd47853f --- /dev/null +++ b/moonv4/moon_gui/delivery/html/project/action/mapping/project-map.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html b/moonv4/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html new file mode 100644 index 00000000..bde6982e --- /dev/null +++ b/moonv4/moon_gui/delivery/html/project/action/mapping/project-unmap.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/project/action/project-add.tpl.html b/moonv4/moon_gui/delivery/html/project/action/project-add.tpl.html new file mode 100644 index 00000000..612aa9b5 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/project/action/project-add.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/project/action/project-delete.tpl.html b/moonv4/moon_gui/delivery/html/project/action/project-delete.tpl.html new file mode 100644 index 00000000..a3a2d3e4 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/project/action/project-delete.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/project/action/project-view.tpl.html b/moonv4/moon_gui/delivery/html/project/action/project-view.tpl.html new file mode 100644 index 00000000..b2bd975b --- /dev/null +++ b/moonv4/moon_gui/delivery/html/project/action/project-view.tpl.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/html/project/project-list.tpl.html b/moonv4/moon_gui/delivery/html/project/project-list.tpl.html new file mode 100644 index 00000000..d0ab8886 --- /dev/null +++ b/moonv4/moon_gui/delivery/html/project/project-list.tpl.html @@ -0,0 +1 @@ +
 
 
 
Name
Domain
Enabled
Description
Mapping
Actions
There is no Projects
Loading PDP
\ No newline at end of file diff --git a/moonv4/moon_gui/delivery/index.html b/moonv4/moon_gui/delivery/index.html new file mode 100644 index 00000000..0631ab7a --- /dev/null +++ b/moonv4/moon_gui/delivery/index.html @@ -0,0 +1,34 @@ + + + + + + + Moon + + + + + + + + +
+
+
+ +
+
+
+ +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/js/app.js b/moonv4/moon_gui/delivery/js/app.js new file mode 100644 index 00000000..9f1f639e --- /dev/null +++ b/moonv4/moon_gui/delivery/js/app.js @@ -0,0 +1,3 @@ +!function(){"use strict";function e(e,s,u,d){s.useStaticFilesLoader({prefix:"assets/i18n/",suffix:".json"}).preferredLanguage("en").useCookieStorage(),d.theme="selectize",e.when("","/project"),e.when("/","/project"),e.otherwise("/404"),t(u),o(u),n(u),a(u),r(u),i(u),c(u),l(u)}function t(e){return e.state("moon",{abstract:!0,template:"
"}).state("moon.404",{url:"/404",templateUrl:"html/common/404/404.tpl.html"}),e}function o(e){return e.state("moon.dashboard",{url:"/dashboard",templateUrl:"html/dashboard/dashboard.tpl.html"}),e}function n(e){return e.state("moon.auth",{abstract:!0,template:"
"}).state("moon.auth.login",{url:"/login",templateUrl:"html/authentication/authentication.tpl.html",controller:"AuthenticationController",controllerAs:"auth"}),e}function r(e){return e.state("moon.model",{abstract:!0,template:"
"}).state("moon.model.list",{url:"/model",templateUrl:"html/model/model-list.tpl.html",controller:"ModelListController",controllerAs:"list",resolve:{models:["modelService",function(e){return e.findAll()}]}}).state("moon.model.edit",{url:"/model/:id",templateUrl:"html/model/edit/model-edit.tpl.html",controller:"ModelEditController",controllerAs:"edit",resolve:{model:["$stateParams","modelService",function(e,t){return t.findOneWithMetaRules(e.id)}]}}),e}function a(e){return e.state("moon.project",{abstract:!0,template:"
"}).state("moon.project.list",{url:"/project",templateUrl:"html/project/project-list.tpl.html",controller:"ProjectListController",controllerAs:"list",resolve:{projects:["projectService",function(e){return e.findAll()}]}}),e}function i(e){return e.state("moon.pdp",{abstract:!0,template:"
"}).state("moon.pdp.list",{url:"/pdp",templateUrl:"html/pdp/pdp-list.tpl.html",controller:"PDPListController",controllerAs:"list",resolve:{pdps:["pdpService",function(e){return e.findAll()}]}}).state("moon.pdp.edit",{url:"/pdp/:id",templateUrl:"html/pdp/edit/pdp-edit.tpl.html",controller:"PDPEditController",controllerAs:"edit",resolve:{pdp:["$stateParams","pdpService",function(e,t){return t.findOne(e.id)}]}}),e}function c(e){return e.state("moon.policy",{abstract:!0,template:"
"}).state("moon.policy.list",{url:"/policy",templateUrl:"html/policy/policy-list.tpl.html",controller:"PolicyListController",controllerAs:"list",resolve:{policies:["policyService",function(e){return e.findAll()}]}}).state("moon.policy.edit",{url:"/policy/:id",templateUrl:"html/policy/edit/policy-edit.tpl.html",controller:"PolicyEditController",controllerAs:"edit",resolve:{policy:["$stateParams","policyService",function(e,t){return t.findOne(e.id)}]}}),e}function l(e){return e.state("moon.logs",{url:"/logs",templateUrl:"html/logs/logs.tpl.html",controller:"LogsController",controllerAs:"logs"}),e}function s(e,t,o,n,r,a,i){function c(e,t,o){["/login"].indexOf(i.path())===-1&&!a.currentUser&&i.path("/login")}function l(){e.connected=r.IsConnected(),e.transitionModal.$promise.then(e.transitionModal.show)}function s(){e.transitionModal.hide()}function u(t,r,a,i,c,l){var s=d(t,r,a,i,c,l);o("moon.global.error",{stacktrace:s}).then(function(e){n.alertError(e)}),e.transitionModal.hide()}function d(e,t,o,n,r,a){var i={};return i.status=a.status,i.message=a.statusText,i.state=t,i.params=o,i}e.connected=r.IsConnected(),e.transitionModal=t({scope:e,template:"html/common/waiting/waiting.tpl.html",backdrop:"static",show:!1}),e.$on("$stateChangeStart",l),e.$on("$stateChangeSuccess",s),e.$on("$stateChangeError",u),e.$on("$locationChangeStart",c),r.IsConnected()&&r.SetTokenHeader(r.GetTokenHeader())}angular.module("moon",["ngResource","ngRoute","ui.router","ngMessages","ui.bootstrap","ngTable","ngCookies","ngStorage","pascalprecht.translate","ngAnimate","mgcrea.ngStrap","NgSwitchery","ui.select","toaster"]).config(e).run(s);e.$inject=["$urlRouterProvider","$translateProvider","$stateProvider","uiSelectConfig"],s.$inject=["$rootScope","$modal","$translate","alertService","authenticationService","$sessionStorage","$location"]}(),function(){"use strict";angular.module("moon").constant("DEFAULT_CST",{DOMAIN:{DEFAULT:"Default"}}).constant("SECURITY_PIPELINE_CST",{TYPE:{POLICY:"policy"}}).constant("META_DATA_CST",{TYPE:{SUBJECT:"SUBJECT",OBJECT:"OBJECT",ACTION:"ACTION"}}).constant("PERIMETER_CST",{TYPE:{SUBJECT:"SUBJECT",OBJECT:"OBJECT",ACTION:"ACTION"}}).constant("DATA_CST",{TYPE:{SUBJECT:"SUBJECT",OBJECT:"OBJECT",ACTION:"ACTION"}}).constant("ASSIGNMENTS_CST",{TYPE:{SUBJECT:"SUBJECT",OBJECT:"OBJECT",ACTION:"ACTION"}}).constant("RULES_CST",{TYPE:{SUBJECT:"SUBJECT",OBJECT:"OBJECT",ACTION:"ACTION"}}).constant("REST_URI",{PDP:"http://172.18.0.11:38001/pdp/",MODELS:"http://172.18.0.11:38001/models/",METARULES:"http://172.18.0.11:38001/meta_rules/",RULES:"http://172.18.0.11:38001/rules/",POLICIES:"http://172.18.0.11:38001/policies/",METADATA:{subject:"http://172.18.0.11:38001/subject_categories/",object:"http://172.18.0.11:38001/object_categories/",action:"http://172.18.0.11:38001/action_categories/"},PERIMETERS:{subject:"http://172.18.0.11:38001/subjects/",object:"http://172.18.0.11:38001/objects/",action:"http://172.18.0.11:38001/actions/"},KEYSTONE:"http://keystone:5000/v3/"})}(),function(){"use strict";function e(e,t,o,n,r){function a(){l.loading=!0,e.Login(l.credentials,i,c)}function i(){t("moon.login.success").then(function(e){o.alertSuccess(e),n.go("moon.dashboard"),l.loading=!1})}function c(e){t("moon.login.error",{errorCode:e.status}).then(function(e){o.alertError(e),l.loading=!1})}var l=this;l.login=a,l.loading=!1,l.credentials={username:"",password:""},function(){r.connected&&n.go("moon.dashboard")}()}angular.module("moon").controller("AuthenticationController",e),e.$inject=["authenticationService","$translate","alertService","$state","$rootScope"]}(),function(){"use strict";function e(){}angular.module("moon").controller("LogsController",e)}(),function(){"use strict";function e(e,t,o,n,r,a){function i(){return S.table=new n({page:1,count:10,sorting:{name:"asc"}},{total:function(){return S.getModels().length},getData:function(e,t){var o=t.sorting()?r("orderBy")(S.getModels(),t.orderBy()):S.getModels();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),S.table}function c(){return S.models?S.models:[]}function l(){return S.getModels().length>0}function s(){S.search.query=""}function u(e){return e.name.indexOf(S.search.query)!==-1||e.description.indexOf(S.search.query)!==-1}function d(){S.add.modal.$promise.then(S.add.modal.show)}function m(e){S.models.push(e)}function p(){S.table.total(S.models.length),S.table.reload()}function f(e,t){m(t),p(),S.add.modal.hide()}function h(e){S.add.modal.hide()}function g(e){S.view.modal.$scope.model=e,S.view.modal.$promise.then(S.view.modal.show)}function v(e){S.del.modal.$scope.model=e,S.del.modal.$promise.then(S.del.modal.show)}function y(e){S.models=_.chain(S.models).reject({id:e.id}).value()}function j(e,t){S.deleteModel(t),S.refreshModels(),S.del.modal.hide()}function b(e,t){S.del.modal.hide()}var S=this;S.models=o,S.table={},S.search={query:"",find:u,reset:s},S.getModels=c,S.hasModels=l,S.deleteModel=y,S.refreshModels=p,S.add={modal:a({template:"html/model/action/model-add.tpl.html",show:!1}),showModal:d},S.view={modal:a({template:"html/model/action/model-view.tpl.html",show:!1}),showModal:g},S.del={modal:a({template:"html/model/action/model-delete.tpl.html",show:!1}),showModal:v},function(){i()}();var $={"event:modelCreatedSuccess":t.$on("event:modelCreatedSuccess",f),"event:modelCreatedError":t.$on("event:modelCreatedError",h),"event:modelDeletedSuccess":t.$on("event:modelDeletedSuccess",j),"event:modelDeletedError":t.$on("event:modelDeletedError",b)};for(var E in $)e.$on("$destroy",$[E])}angular.module("moon").controller("ModelListController",e),e.$inject=["$scope","$rootScope","models","NgTableParams","$filter","$modal"]}(),function(){"use strict";function e(e,t,o,n,r,a,i){function c(){return M.pdps?M.pdps:[]}function l(){return M.getPDPs().length>0}function s(e){M.pdps.push(e)}function u(e){M.pdps=_.chain(M.pdps).reject({id:e.id}).value()}function d(){M.table.total(M.pdps.length),M.table.reload()}function m(e){return _(_.values(M.getPDPs())).each(function(t){t.id===e.id&&(t=_.clone(e))}),M.pdps}function p(e){return e.id}function f(e){return e.tenant.name}function h(e){return e?e.name:""}function g(e){return!_.isNull(e.keystone_project_id)}function v(e){return _.has(e,"project")?e.project:(_.has(e,"callPdpInProgress")||(e.callPdpInProgress=!0,i.findOne(e.keystone_project_id,function(t){return e.callPdpInProgress=!1,e.project=t,e.project})),!1)}function y(){return M.table=new r({page:1,count:10,sorting:{name:"asc"}},{total:function(){return M.getPDPs().length},getData:function(e,t){var n=t.sorting()?o("orderBy")(M.getPDPs(),t.orderBy()):M.getPDPs();e.resolve(n.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),M.table}function j(e){return M.getPDPName(e).indexOf(M.search.query)!==-1||M.getSecPipelineFromPdp(e).indexOf(M.search.query)!==-1}function b(e){return e.security_pipeline?e.security_pipeline:[]}function S(){M.search.query=""}function $(){M.add.modal.$promise.then(M.add.modal.show)}function E(e,t){M.addPDP(t),M.refreshPDPs(),M.add.modal.hide()}function P(e,t){M.add.modal.hide()}function T(e){M.del.modal.$scope.pdp=e,M.del.modal.$promise.then(M.del.modal.show)}function C(e,t){M.deletePDP(t),M.refreshPDPs(),M.del.modal.hide()}function O(){M.del.modal.hide()}var M=this;M.pdps=a,M.mappings=[],M.getPDPs=c,M.hasPDPs=l,M.getPDPName=h,M.isMapped=g,M.getProjectFromPDP=v,M.getidFromPDP=p,M.table={},M.addPDP=s,M.deletePDP=u,M.refreshPDPs=d,M.updatePDPs=m,M.getMappedProjectName=f,M.getSecPipelineFromPdp=b,M.search={query:"",find:j,reset:S},M.add={modal:n({template:"html/pdp/action/pdp-add.tpl.html",show:!1}),showModal:$},M.del={modal:n({template:"html/pdp/action/pdp-delete.tpl.html",show:!1}),showModal:T},function(){y()}();var A={"event:pdpCreatedSuccess":e.$on("event:pdpCreatedSuccess",E),"event:pdpCreatedError":e.$on("event:pdpCreatedError",P),"event:pdpDeletedSuccess":e.$on("event:pdpDeletedSuccess",C),"event:pdpDeletedError":e.$on("event:pdpDeletedError",O)};for(var R in A)t.$on("$destroy",A[R])}angular.module("moon").controller("PDPListController",e),e.$inject=["$rootScope","$scope","$filter","$modal","ngTableParams","pdps","projectService"]}(),function(){"use strict";function e(e,t,o,n,r,a){function i(){return b.policies?b.policies:[]}function c(){return b.getPolicies().length>0}function l(){return b.table=new o({page:1,count:10,sorting:{name:"asc",genre:"asc"}},{total:function(){return b.getPolicies().length},getData:function(e,t){var o=t.sorting()?n("orderBy")(b.getPolicies(),t.orderBy()):b.getPolicies();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),b.table}function s(e){return e.name.indexOf(b.search.query)!==-1||e.genre.indexOf(b.search.query)!==-1||e.description.indexOf(b.search.query)!==-1}function u(){b.search.query=""}function d(){b.add.modal.$promise.then(b.add.modal.show)}function m(e,t){b.addPolicy(t),b.refreshPolicies(),b.add.modal.hide()}function p(e,t){b.add.modal.hide()}function f(e){b.policies.push(e)}function h(){b.table.total(b.policies.length),b.table.reload()}function g(e){b.del.modal.$scope.policy=e,b.del.modal.$promise.then(b.del.modal.show)}function v(e){b.policies=_.chain(b.policies).reject({id:e.id}).value()}function y(e,t){b.deletePolicy(t),b.refreshPolicies(),b.del.modal.hide()}function j(e,t){b.del.modal.hide()}var b=this;b.policies=t,b.getPolicies=i,b.hasPolicies=c,b.addPolicy=f,b.refreshPolicies=h,b.deletePolicy=v,b.table={},b.search={query:"",find:s,reset:u},b.add={modal:r({template:"html/policy/action/policy-add.tpl.html",show:!1}),showModal:d},b.del={modal:r({template:"html/policy/action/policy-delete.tpl.html",show:!1}),showModal:g},function(){l()}();var S={"event:policyCreatedSuccess":a.$on("event:policyCreatedSuccess",m),"event:policyCreatedError":a.$on("event:policyCreatedError",p),"event:policyDeletedSuccess":a.$on("event:policyDeletedSuccess",y),"event:policyDeletedError":a.$on("event:policyDeletedError",j)};for(var $ in S)e.$on("$destroy",S[$])}angular.module("moon").controller("PolicyListController",e),e.$inject=["$scope","policies","ngTableParams","$filter","$modal","$rootScope"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/policy-mapped-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{pdp:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a){function i(e){v.policiesId=v.pdp.security_pipeline,a.findSomeWithCallback(v.policiesId,function(t){v.policies=t,v.loadingPolicies=!1,e?u():c()})}function c(){return v.table=new o({page:1,count:10,sorting:{name:"asc"}},{total:function(){return v.getPolicies().length},getData:function(e,t){var o=t.sorting()?r("orderBy")(v.getPolicies(),t.orderBy()):v.getPolicies();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),v.table}function l(){return v.policies?v.policies:[]}function s(){return v.getPolicies().length>0}function u(){v.table.total(v.getPolicies().length),v.table.reload()}function d(){v.map.modal.$scope.pdp=v.pdp,v.map.modal.$promise.then(v.map.modal.show)}function m(e){v.unmap.modal.$scope.pdp=v.pdp,v.unmap.modal.$scope.policy=e,v.unmap.modal.$promise.then(v.unmap.modal.show)}function p(e,t){v.pdp=t,i(!0),v.map.modal.hide()}function f(e){v.map.modal.hide()}function h(e,t){v.pdp=t,i(!0),v.unmap.modal.hide()}function g(e){v.unmap.modal.hide()}var v=this;v.table={},v.pdp=e.list.pdp,v.getPolicies=l,v.hasPolicies=s,v.refreshPolicies=u,v.loadingPolicies=!0,v.policies=[],function(){i(!1)}(),v.map={modal:n({template:"html/policy/action/mapping/policy-map.tpl.html",show:!1}),showModal:d},v.unmap={modal:n({template:"html/policy/action/mapping/policy-unmap.tpl.html",show:!1}),showModal:m};var y={"event:policyMapToPdpSuccess":t.$on("event:policyMapToPdpSuccess",p),"event:policyMapToPdpError":t.$on("event:policyMapToPdpError",f),"event:policyUnMappedToPdpSuccess":t.$on("event:policyUnMappedToPdpSuccess",h),"event:policyUnMappedToPdpError":t.$on("event:policyUnMappedToPdpError",g)};for(var j in y)e.$on("$destroy",y[j])}angular.module("moon").directive("moonPolicyMappedList",e),e.$inject=[],angular.module("moon").controller("moonPolicyMappedListController",t),t.$inject=["$scope","$rootScope","NgTableParams","$modal","$filter","policyService"]}(),function(){"use strict";function e(e,t,o,n,r,a,i){function c(){N.loadingPDPs=!0,h(),a.findAllWithCallBack(function(e){N.pdps=e,a.mapPdpsToProjects(N.projects,N.pdps),N.loadingPDPs=!1})}function l(){return N.projects?N.projects:[]}function s(){return N.getProjects().length>0}function u(e){return _.has(e,"pdp")}function d(e){return e.pdp}function m(e){N.projects.push(e)}function p(e){N.projects=_.chain(N.projects).reject({id:e.id}).value()}function f(){N.table.total(N.projects.length),N.table.reload()}function h(){return N.table=new r({page:1,count:10,sorting:{name:"asc"}},{total:function(){return N.getProjects().length},getData:function(e,t){var n=t.sorting()?o("orderBy")(N.getProjects(),t.orderBy()):N.getProjects();e.resolve(n.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),N.table}function g(e){return _.has(e,"pdp")?e.pdp.name:"error"}function v(e){return e.name.indexOf(N.search.query)!==-1||e.description.indexOf(N.search.query)!==-1}function y(){N.search.query=""}function j(){N.add.modal.$promise.then(N.add.modal.show)}function b(e,t){N.addProject(t),N.refreshProjects(),N.add.modal.hide()}function S(e,t){N.add.modal.hide()}function $(e){N.del.modal.$scope.project=e,N.del.modal.$promise.then(N.del.modal.show)}function E(e,t){N.deleteProject(t),N.refreshProjects(),N.del.modal.hide()}function P(e,t){N.del.modal.hide()}function T(e){N.map.modal.$scope.project=e,N.map.modal.$promise.then(N.map.modal.show)}function C(e,t){c(),N.map.modal.hide()}function O(e,t){N.map.modal.hide()}function M(e){N.unmap.modal.$scope.project=e,N.unmap.modal.$promise.then(N.unmap.modal.show)}function A(e,t){var o=_.findIndex(N.projects,function(e){return t.id===e.id});if(o===-1)return N.unmap.modal.hide(),!1;N.projects[o]=t,N.refreshProjects(),N.unmap.modal.hide()}function R(e,t){N.unmap.modal.hide()}function D(e){N.view.modal.$scope.project=e,N.view.modal.$promise.then(N.view.modal.show)}var N=this;N.projects=i,N.pdps=[],N.getProjects=l,N.hasProjects=s,N.isProjectMapped=u,N.table={},N.addProject=m,N.deleteProject=p,N.refreshProjects=f,N.getMappedPDPName=g,N.getPdpFromProject=d,N.search={query:"",find:v,reset:y},N.add={modal:n({template:"html/project/action/project-add.tpl.html",show:!1}),showModal:j},N.del={modal:n({template:"html/project/action/project-delete.tpl.html",show:!1}),showModal:$},N.map={modal:n({template:"html/project/action/mapping/project-map.tpl.html",show:!1}),showModal:T},N.unmap={modal:n({template:"html/project/action/mapping/project-unmap.tpl.html",show:!1}),showModal:M},N.view={modal:n({template:"html/project/action/project-view.tpl.html",show:!1}),showModal:D},c();var w={"event:projectCreatedSuccess":e.$on("event:projectCreatedSuccess",b),"event:projectCreatedError":e.$on("event:projectCreatedError",S),"event:projectDeletedSuccess":e.$on("event:projectDeletedSuccess",E),"event:projectDeletedError":e.$on("event:projectDeletedError",P),"event:projectMappedSuccess":e.$on("event:projectMappedSuccess",C),"event:projectMappedError":e.$on("event:projectMappedError",O),"event:projectUnmappedSuccess":e.$on("event:projectUnmappedSuccess",A),"event:projectUnmappedError":e.$on("event:projectUnmappedError",R)};for(var I in w)t.$on("$destroy",w[I])}angular.module("moon").controller("ProjectListController",e),e.$inject=["$rootScope","$scope","$filter","$modal","ngTableParams","pdpService","projects"]}(),function(){"use strict";function e(e,t){function o(){n.browsersModal.$promise.then(n.browsersModal.show)}var n=this;n.version=null,n.browsersModal=null,n.showBrowsersCompliance=o,function(){n.browsersModal=e({template:"html/common/compatibility/compatibility.tpl.html",show:!1}),n.browsersModal}(),function(){var e=n;t.version.get().$promise.then(function(t){return e.version=t.version?t.version:"SNAPSHOT",e.version})}()}angular.module("moon").controller("FooterController",e),e.$inject=["$modal","versionService"]}(),function(){"use strict";function e(e,t,o,n){function r(t,o){o.preventDefault(),e.use(t),e.preferredLanguage(t)}function a(){o.Logout(),e("moon.logout.success").then(function(e){n.alertSuccess(e)})}var i=this;i.isProjectTabActive=t.isProjectTabActive,i.isPDPTabActive=t.isPDPTabActive,i.isLogsTabActive=t.isLogsTabActive,i.isPolicyTabActive=t.isPolicyTabActive,i.isModelTabActive=t.isModelTabActive,i.changeLocale=r,i.logout=a,i.getUser=o.GetUser}angular.module("moon").controller("HeaderController",e),e.$inject=["$translate","menuService","authenticationService","alertService"]}(),function(){"use strict";function e(){return{templateUrl:"html/common/loader/loader.tpl.html",restrict:"E"}}angular.module("moon").directive("moonLoader",e),e.$inject=[]}(),function(){"use strict";function e(e,t,o,n,r,a){function i(){function i(t){var r=a.transformOne(t,"models");n("moon.model.add.success",{modelName:r.name}).then(function(e){o.alertSuccess(e)}),c.loading=!1,e.$emit("event:modelCreatedSuccess",r)}function l(t){n("moon.model.add.error",{modelName:c.model.name}).then(function(e){o.alertError(e)}),c.loading=!1,e.$emit("event:modelCreatedError",c.project)}r.isInvalid(c.form)?r.checkFieldsValidity(c.form):(c.loading=!0,t.data.create({},c.model,i,l))}var c=this;c.form={},c.loading=!1,c.model={name:null,description:null,meta_rules:[]},c.create=i}angular.module("moon").controller("ModelAddController",e),e.$inject=["$scope","modelService","alertService","$translate","formService","utilService"]}(),function(){"use strict";function e(e,t,o,n){function r(){function r(n){t("moon.model.remove.success",{modelName:a.model.name}).then(function(e){o.alertSuccess(e)}),a.loading=!1,e.$emit("event:modelDeletedSuccess",a.model)}function i(n){t("moon.model.remove.error",{modelName:a.model.name,errorCode:n.data.error.code,message:n.data.error.message}).then(function(e){o.alertError(e)}),a.loading=!1,e.$emit("event:modelDeletedError",a.model)}a.loading=!0,n.delete(a.model,r,i)}var a=this;a.model=e.model,a.loading=!1,a.remove=r}angular.module("moon").controller("ModelDeleteController",e),e.$inject=["$scope","$translate","alertService","modelService"]}(),function(){"use strict";function e(e,t){function o(){t.findSomeWithMetaData(n.model.meta_rules).then(function(e){n.meta_rules_values=e,n.model.meta_rules_values=e})}var n=this;n.model=e.model,n.meta_rules_values=!1,function(){n.model.meta_rules.length>0?o():n.meta_rules_values=[]}()}angular.module("moon").controller("ModelViewController",e),e.$inject=["$scope","metaRuleService"]}(),function(){"use strict";function e(e,t,o,n){function r(e,t){a.model=t}var a=this;a.model=o,a.editBasic=!1,a.editMetaRules=!0;var i={"event:modelUpdatedSuccess":t.$on("event:modelUpdatedSuccess",r),"event:updateModelFromMetaRuleAddSuccess":t.$on("event:updateModelFromMetaRuleAddSuccess",r)};for(var c in i)e.$on("$destroy",i[c])}angular.module("moon").controller("ModelEditController",e),e.$inject=["$scope","$rootScope","model","$stateParams"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/model-edit-basic.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{model:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a){function i(){function i(t){var o=a.transformOne(t,"models");r("moon.model.edit.basic.success",{modelName:o.name}).then(function(e){n.alertSuccess(e)}),l.loading=!1,e.$emit("event:modelUpdatedSuccess",o)}function c(e){r("moon.model.edit.basic.error",{modelName:l.model.name}).then(function(e){n.alertError(e)}),l.loading=!1}o.isInvalid(l.form)?o.checkFieldsValidity(l.form):(l.loading=!0,t.update(l.modelToEdit,i,c))}function c(){l.modelToEdit=angular.copy(l.model)}var l=this;l.editModel=i,l.init=c,l.form={},function(){l.model=e.edit.model,l.modelToEdit=angular.copy(l.model)}()}angular.module("moon").directive("moonModelEditBasic",e),e.$inject=[],angular.module("moon").controller("moonModelEditBasicController",t),t.$inject=["$scope","modelService","formService","alertService","$translate","utilService"]}(),function(){"use strict";function e(e,t,o,n,r,a,i){function c(a){function c(n){t("moon.pdp.add.success",{pdpName:a.name}).then(function(e){o.alertSuccess(e)});var r=i.transformOne(n,"pdps");l.loading=!1,e.$emit("event:pdpCreatedSuccess",r)}function s(n){t("moon.pdp.add.error",{pdpName:a.name}).then(function(e){o.alertError(e)}),l.loading=!1,e.$emit("event:pdpCreatedError")}n.isInvalid(l.form)?n.checkFieldsValidity(l.form):(l.loading=!0,r.data.pdp.create({},{name:l.pdp.name,description:l.pdp.description,security_pipeline:[l.selectedPolicy.id],keystone_project_id:null},c,s))}var l=this;l.form={},l.pdp={},l.policies=[],l.selectedPolicy=null,l.loading=!1,l.loadingPolicies=!0,l.create=c,function(){a.findAllWithCallback(function(e){l.policies=e,l.loadingPolicies=!1})}()}angular.module("moon").controller("PDPAddController",e),e.$inject=["$scope","$translate","alertService","formService","pdpService","policyService","utilService"]}(),function(){"use strict";function e(e,t,o,n){function r(){function r(n){t("moon.pdp.remove.success",{pdpName:a.pdp.name}).then(function(e){o.alertSuccess(e)}),a.loading=!1,e.$emit("event:pdpDeletedSuccess",a.pdp)}function i(n){t("moon.pdp.remove.error",{pdpName:a.pdp.name}).then(function(e){o.alertError(e)}),a.loading=!1,e.$emit("event:pdpDeletedError",a.pdp)}a.loading=!0,n.data.pdp.remove({pdp_id:a.pdp.id},r,i)}var a=this;a.pdp=e.pdp,a.loading=!1,a.remove=r}angular.module("moon").controller("PDPDeleteController",e),e.$inject=["$scope","$translate","alertService","pdpService"]}(),function(){"use strict";function e(e,t,o,n){function r(e,t){a.pdp=t}var a=this;a.pdp=o,a.editBasic=!1;var i={"event:pdpUpdatedSuccess":t.$on("event:pdpUpdatedSuccess",r)};for(var c in i)e.$on("$destroy",i[c])}angular.module("moon").controller("PDPEditController",e),e.$inject=["$scope","$rootScope","pdp","$stateParams"]}(),function(){"use strict";function e(){return{templateUrl:"html/pdp/edit/pdp-edit-basic.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{pdp:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a){function i(){function i(t){var o=a.transformOne(t,"pdps");r("moon.pdp.edit.basic.success",{pdpName:o.name}).then(function(e){n.alertSuccess(e)}),l.loading=!1,e.$emit("event:pdpUpdatedSuccess",o)}function c(e){r("moon.pdp.edit.basic.error",{pdpName:l.pdp.name}).then(function(e){n.alertError(e)}),l.loading=!1}o.isInvalid(l.form)?o.checkFieldsValidity(l.form):(l.loading=!0,t.update(l.pdpToEdit,i,c))}function c(){l.pdpToEdit=angular.copy(l.pdp)}var l=this;l.editPdp=i,l.init=c,l.form={},function(){l.pdp=e.edit.pdp,l.pdpToEdit=angular.copy(l.pdp)}()}angular.module("moon").directive("moonPDPEditBasic",e),e.$inject=[],angular.module("moon").controller("moonPDPEditBasicController",t),t.$inject=["$scope","pdpService","formService","alertService","$translate","utilService"]}(),function(){"use strict";function e(e,t,o,n,r,a,i){function c(){i.findAllWithCallBack(l)}function l(e){u.models=e,u.modelsLoading=!1}function s(){function i(n){var r=a.transformOne(n,"policies");t("moon.policy.add.success",{policyName:r.name}).then(function(e){o.alertSuccess(e)}),u.loading=!1,e.$emit("event:policyCreatedSuccess",r)}function c(n){t("moon.policy.add.error",{policyName:u.model.name}).then(function(e){o.alertError(e)}),u.loading=!1,e.$emit("event:policyCreatedError",u.project)}n.isInvalid(u.form)?n.checkFieldsValidity(u.form):(u.loading=!0,r.data.policy.create({},{name:u.policy.name,description:u.policy.description,genre:[u.selectedGenre],model_id:u.selectedModel.id},i,c))}var u=this;u.loading=!1,u.form={},u.policy={name:null,genre:null,description:null,model_id:null},u.genres=["admin","authz"],u.models=[],u.modelsLoading=!0,u.create=s,function(){c()}()}angular.module("moon").controller("PolicyAddController",e),e.$inject=["$scope","$translate","alertService","formService","policyService","utilService","modelService"]}(),function(){"use strict";function e(e,t,o,n){function r(){function r(n){t("moon.policy.remove.success",{policyName:a.policy.name}).then(function(e){o.alertSuccess(e)}),a.loading=!1,e.$emit("event:policyDeletedSuccess",a.policy)}function i(n){t("moon.policy.remove.error",{policyName:a.policy.name,errorCode:n.data.error.code,message:n.data.error.message}).then(function(e){o.alertError(e)}),a.loading=!1,e.$emit("event:policyDeletedError",a.policy)}a.loading=!0,n.delete(a.policy,r,i)}var a=this;a.policy=e.policy,a.loading=!1,a.remove=r}angular.module("moon").controller("PolicyDeleteController",e),e.$inject=["$scope","$translate","alertService","policyService"]}(),function(){"use strict";function e(e,t,o,n){function r(){i.loadingModel=!0,n.findOneWithCallback(i.policy.model_id,function(e){i.loadingModel=!1,i.policy.model=e})}function a(e,t){i.policy=t,r()}var i=this;i.policy=o,i.editBasic=!1,i.showPerimeters=!1,i.showData=!1,i.showRules=!1,i.showAssignments=!1,function(){r()}();var c={"event:policyUpdatedSuccess":t.$on("event:policyUpdatedSuccess",a)};for(var l in c)e.$on("$destroy",c[l])}angular.module("moon").controller("PolicyEditController",e),e.$inject=["$scope","$rootScope","policy","modelService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/policy-edit-basic.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{policy:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a,i){function c(){i.findAllWithCallBack(l)}function l(e){d.models=e,_.each(e,function(e){e.id===d.policy.model_id&&(d.selectedModel=e)}),d.modelsLoading=!1}function s(){function i(t){var o=a.transformOne(t,"policies");r("moon.policy.edit.basic.success",{policyName:o.name}).then(function(e){n.alertSuccess(e)}),d.loading=!1,e.$emit("event:policyUpdatedSuccess",o)}function c(e){r("moon.policy.edit.basic.error",{policyName:d.policy.name}).then(function(e){n.alertError(e)}),d.loading=!1}o.isInvalid(d.form)?o.checkFieldsValidity(d.form):(d.loading=!0,delete d.policyToEdit.model,d.policyToEdit.model_id=d.selectedModel.id,t.update(d.policyToEdit,i,c))}function u(){d.policyToEdit=angular.copy(d.policy)}var d=this;d.editPolicy=s,d.init=u,d.form={},d.modelsLoading=!0,function(){d.policy=e.edit.policy,d.policyToEdit=angular.copy(d.policy),console.log(d.policyToEdit),c()}()}angular.module("moon").directive("moonPolicyEditBasic",e),e.$inject=[],angular.module("moon").controller("moonPolicyEditBasicController",t),t.$inject=["$scope","policyService","formService","alertService","$translate","utilService","modelService"]}(),function(){"use strict";function e(e,t,o,n,r,a){function i(){function a(n){var r=n.project;t("moon.project.add.success",{projectName:r.name}).then(function(e){o.alertSuccess(e)}),c.loading=!1,e.$emit("event:projectCreatedSuccess",r)}function i(n){t("moon.project.add.error",{projectName:c.project.project.name}).then(function(e){o.alertError(e)}),c.loading=!1,e.$emit("event:projectCreatedError",c.project)}n.isInvalid(c.form)?n.checkFieldsValidity(c.form):(c.loading=!0,r.data.projects.create({},c.project,a,i))}var c=this;c.form={},c.loading=!1,c.project={project:{name:null,description:null,enabled:!0,domain:a.DOMAIN.DEFAULT}},c.create=i}angular.module("moon").controller("ProjectAddController",e),e.$inject=["$scope","$translate","alertService","formService","projectService","DEFAULT_CST"]}(),function(){"use strict";function e(e,t,o,n,r){function a(){r.findAllWithCallBack(function(e){u.pdps=e,r.mapPdpsToProject(u.project,u.pdps),u.loadingPDP=!1})}function i(){return _.has(u.project,"pdp")}function c(){u.loading=!0,i()?l(s):s()}function l(n){function a(n){t("moon.project.remove.mapping.remove.error",{pdpName:i}).then(function(e){o.alertError(e)}),u.loading=!1,e.$emit("event:projectDeletedError",u.project)}var i=unmap.project.pdp.name;r.unMap(unmap.project,n,a)}function s(){function r(n){t("moon.project.remove.success",{projectName:u.project.name}).then(function(e){o.alertSuccess(e)}),u.loading=!1,e.$emit("event:projectDeletedSuccess",u.project)}function a(n){t("moon.project.remove.error",{projectName:u.project.name,errorCode:n.data.error.code,message:n.data.error.message}).then(function(e){o.alertError(e)}),u.loading=!1,e.$emit("event:projectDeletedError",u.project)}n.data.projects.remove({project_id:u.project.id},r,a)}var u=this;u.project=e.project,u.loading=!1,u.loadingPDP=!0,u.remove=c,u.isProjectMapped=i,u.pdps=[],function(){a()}()}angular.module("moon").controller("ProjectDeleteController",e),e.$inject=["$scope","$translate","alertService","projectService","pdpService"]}(),function(){"use strict";function e(e,t,o,n,r){this.project=t.project}angular.module("moon").controller("ProjectViewController",e),e.$inject=["$q","$scope","$translate","alertService","projectService"]}(),function(){"use strict";function e(e){function t(t){e.pop("error",null,t,5e3)}function o(t){e.pop("success",null,t,5e3)}function n(t){e.pop("note",null,t,5e3)}var r={};return r.alertError=t,r.alertSuccess=o,r.alertInfo=n,r}angular.module("moon").factory("alertService",e),e.$inject=["toaster"]}(),function(){"use strict";function e(){function e(){var e,t=navigator.userAgent,o=t.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i)||[];return/trident/i.test(o[1])?(e=/\brv[ :]+(\d+)/g.exec(t)||[],"IE "+(e[1]||"")):"Chrome"===o[1]&&null!=(e=t.match(/\bOPR\/(\d+)/))?"Opera "+e[1]:(o=o[2]?[o[1],o[2]]:[navigator.appName,navigator.appVersion,"-?"],null!=(e=t.match(/version\/(\d+)/i))&&o.splice(1,1,e[1]),o.join(" "))}var t={};return t.sayWho=e,t}angular.module("moon").factory("browserService",e)}(),function(){"use strict";function e(){function e(e){return e.$invalid}function t(e){var t=_.keys(e.$error);_(t).each(function(t){ +var o=_.values(e.$error[t]);_(o).each(function(e){e.$dirty=!0,e.$setValidity(t,!1)})})}var o={};return o.isInvalid=e,o.checkFieldsValidity=t,o}angular.module("moon").factory("formService",e)}(),function(){"use strict";function e(e){function t(){return e.includes("moon.project")}function o(){return e.includes("moon.pdp")}function n(){return e.includes("moon.policy")}function r(){return e.includes("moon.logs")}function a(){return e.includes("moon.model")}var i={};return i.isProjectTabActive=t,i.isPDPTabActive=o,i.isPolicyTabActive=n,i.isLogsTabActive=r,i.isModelTabActive=a,i}angular.module("moon").factory("menuService",e),e.$inject=["$state"]}(),function(){"use strict";function e(e,t){function o(o){switch(o){case e.TYPE.POLICY:return t.findAll();default:return t.findAll()}}var n={};return n.findAll=o,n}angular.module("moon").factory("securityPipelineService",e),e.$inject=["SECURITY_PIPELINE_CST","policyService"]}(),function(){"use strict";function e(){return{transform:function(e,t){var o=[];return _.each(e[t],function(e,t){e.id=t,o.push(e)}),o},transformOne:function(e,t){var o=[];return _.each(e[t],function(e,t){e.id=t,o.push(e)}),o[0]}}}angular.module("moon").factory("utilService",e),e.$inject=[]}(),function(){"use strict";function e(e){return{version:e("version.json",{},{get:{method:"GET",isArray:!1}})}}angular.module("moon").factory("versionService",e),e.$inject=["$resource"]}(),function(){"use strict";function e(e,t,o,n){function r(e,t){_.each(e,function(e){return a(e,t)})}function a(e,t){if(_.isNull(e.keystone_project_id))return!1;var o=_.findIndex(t,function(t){return e.id===t.keystone_project_id});return o!==-1&&(e.pdp=t[o],!0)}return{data:{pdp:t(o.PDP+":pdp_id",{},{query:{method:"GET",isArray:!1},get:{method:"GET",isArray:!1},create:{method:"POST"},update:{method:"PATCH"},remove:{method:"DELETE"}})},findAll:function(){return this.data.pdp.query().$promise.then(function(e){return n.transform(e,"pdps")})},findAllWithCallBack:function(e){return this.data.pdp.query().$promise.then(function(t){e(n.transform(t,"pdps"))})},findOne:function(e){return this.data.pdp.get({pdp_id:e}).$promise.then(function(e){return n.transformOne(e,"pdps")})},unMap:function(e,t,o){e.keystone_project_id=null,_.has(e,"project")&&delete e.project,this.data.pdp.update({pdp_id:e.id},e,t,o)},map:function(e,t,o,n){e.keystone_project_id=t,this.data.pdp.update({pdp_id:e.id},e,o,n)},update:function(e,t,o){this.data.pdp.update({pdp_id:e.id},e,t,o)},mapPdpsToProjects:r,mapPdpsToProject:a}}angular.module("moon").factory("pdpService",e),e.$inject=["$q","$resource","REST_URI","utilService"]}(),function(){"use strict";function e(e,t,o,n,r){function a(){return _.has(o,"currentUser")}function i(){delete o.currentUser,n.defaults.headers.common["X-Auth-Token"]="",r.path("/")}function c(){return o.currentUser}function l(){return o.currentUser.connectionToken}function s(e){n.defaults.headers.common["X-Auth-Token"]=e}return{data:e(t.KEYSTONE+"auth/tokens",{},{login:{method:"POST",transformResponse:function(e,t){var o={};return o.data=angular.fromJson(e),o.headers=t(),o}},logout:{method:"DELETE"}}),Login:function(e,t,n){var r={auth:{identity:{methods:["password"],password:{user:{name:e.username,domain:{name:"Default"},password:e.password}}},scope:{project:{name:"admin",domain:{name:"Default"}}}}};this.data.login({},r,function(e){o.currentUser=e.data,o.currentUser.connectionToken=e.headers["x-subject-token"],s(e.headers["x-subject-token"]),t()},n)},IsConnected:a,SetTokenHeader:s,GetTokenHeader:l,GetUser:c,Logout:i}}angular.module("moon").factory("authenticationService",e),e.$inject=["$resource","REST_URI","$sessionStorage","$http","$location"]}(),function(){"use strict";function e(e){return{data:{image:e("./pip/nova/images",{},{query:{method:"GET",isArray:!1}}),flavor:e("./pip/nova/flavors",{},{query:{method:"GET",isArray:!1}})}}}angular.module("moon").factory("novaService",e),e.$inject=["$resource"]}(),function(){"use strict";function e(e,t){return{data:{projects:e(t.KEYSTONE+"projects/:project_id",{},{query:{method:"GET",isArray:!1},get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})},findOne:function(e,t){return this.data.projects.get({project_id:e}).$promise.then(function(e){t(e.project)})},findAll:function(){return this.data.projects.query().$promise.then(function(e){var t=[];return _.each(e.projects,function(e){t.push(e)}),t})}}}angular.module("moon").factory("projectService",e),e.$inject=["$resource","REST_URI"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metadata/metadata-edit.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{metaDataType:"=",metaRule:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a,i,c){function l(){function e(e){g.list=e}switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.findAllWithCallback(e);break;case o.TYPE.OBJECT:t.object.findAllWithCallback(e);break;case o.TYPE.ACTION:t.action.findAllWithCallback(e);break;default:g.list=[]}}function s(){function t(t){r("moon.model.metarules.update.success",{metaRuleName:l.name}).then(function(e){n.alertSuccess(e)}),l=c.transformOne(t,"meta_rules"),e.$emit("event:updateMetaRuleFromMetaDataAddSuccess",l),f()}function a(e){r("moon.model.metarules.update.error",{metaRuleName:l.name,reason:e.message}).then(function(e){n.alertError(e)}),f()}if(g.selectedMetaData){var l=g.metaRule;switch(g.metaDataType){case o.TYPE.SUBJECT:l.subject_categories.push(g.selectedMetaData.id);break;case o.TYPE.OBJECT:l.object_categories.push(g.selectedMetaData.id);break;case o.TYPE.ACTION:l.action_categories.push(g.selectedMetaData.id)}i.update(l,t,a)}}function u(){function e(e){var t={};switch(g.metaDataType){case o.TYPE.SUBJECT:t=c.transformOne(e,"subject_categories");break;case o.TYPE.OBJECT:t=c.transformOne(e,"object_categories");break;case o.TYPE.ACTION:t=c.transformOne(e,"action_categories")}r("moon.model.metadata.edit.create.success",{name:t.name}).then(function(e){n.alertSuccess(e)}),f(),g.list.push(t),h()}function i(e){r("moon.model.metadata.edit.create.error",{name:l.name}).then(function(e){n.alertError(e)}),f()}if(a.isInvalid(g.form))a.checkFieldsValidity(g.form);else{p();var l=angular.copy(g.metaData);switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.add(l,e,i);break;case o.TYPE.OBJECT:t.object.add(l,e,i);break;case o.TYPE.ACTION:t.action.add(l,e,i)}}}function d(){function a(t){r("moon.model.metadata.edit.delete.success",{name:s.name}).then(function(e){n.alertSuccess(e)}),i.findOneWithMetaData(g.metaRule.id).then(function(t){g.metaRule=t,m(),l(),f(),e.$emit("event:deleteMetaDataFromMetaDataAddSuccess",g.metaRule)})}function c(e){r("moon.model.metadata.edit.delete.error",{name:s.name}).then(function(e){n.alertError(e)}),f()}if(g.selectedMetaData){p();var s=angular.copy(g.selectedMetaData);switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.delete(s,a,c);break;case o.TYPE.OBJECT:t.object.delete(s,a,c);break;case o.TYPE.ACTION:t.action.delete(s,a,c)}}}function m(){delete g.selectedMetaData}function p(){g.loading=!0}function f(){g.loading=!1}function h(){g.fromList=!0}var g=this;g.metaDataType=e.edit.metaDataType,g.metaRule=e.edit.metaRule,g.fromList=!0,g.laoading=!1,g.form={},g.metaData={name:null,description:null},g.list=[],g.create=u,g.addToMetaRule=s,g.deleteMetaData=d,l()}angular.module("moon").directive("moonMetaDataEdit",e),e.$inject=[],angular.module("moon").controller("moonMetaDataEditController",t),t.$inject=["$scope","metaDataService","META_DATA_CST","alertService","$translate","formService","metaRuleService","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metadata/metadata-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{metaRule:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a,i,c){function l(){s(),u(),d()}function s(){C.loadingCatSub=!0,o.subject.findSomeWithCallback(C.metaRule.subject_categories,function(e){C.catSub=e,C.loadingCatSub=!1})}function u(){C.loadingCatObj=!0,o.object.findSomeWithCallback(C.metaRule.object_categories,function(e){C.catObj=e,C.loadingCatObj=!1})}function d(){C.loadingCatAct=!0,o.action.findSomeWithCallback(C.metaRule.action_categories,function(e){C.catAct=e,C.loadingCatAct=!1})}function m(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:C.metaRule.name}).then(function(e){r.alertSuccess(e)}),C.metaRule=a.findMetaDataFromMetaRule(c.transformOne(t,"meta_rules")),l(),e.loader=!1}function o(t){n("moon.model.metarules.update.error",{metaRuleName:C.metaRule.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(C.metaRule);i.subject_categories=_.without(i.subject_categories,e.id),a.update(i,t,o)}function p(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:C.metaRule.name}).then(function(e){r.alertSuccess(e)}),C.metaRule=a.findMetaDataFromMetaRule(c.transformOne(t,"meta_rules")),l(),e.loader=!1}function o(t){n("moon.model.metarules.update.error",{metaRuleName:C.metaRule.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(C.metaRule);i.object_categories=_.without(i.object_categories,e.id),a.update(i,t,o)}function f(e){function t(t){n("moon.model.metarules.update.success",{metaRuleName:C.metaRule.name}).then(function(e){r.alertSuccess(e)}),C.metaRule=a.findMetaDataFromMetaRule(c.transformOne(t,"meta_rules")),l(),e.loader=!1}function o(t){n("moon.model.metarules.update.error",{metaRuleName:C.metaRule.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(C.metaRule);i.action_categories=_.without(i.action_categories,e.id),a.update(i,t,o)}function h(e){function t(t){n("moon.model.metadata.subject.delete.success",{subjectName:e.name}).then(function(e){r.alertSuccess(e)}),S(e),e.loader=!1}function a(t){n("moon.model.metadata.subject.delete.error",{subjectName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.subject.delete(e,t,a)}function g(e){function t(t){n("moon.model.metadata.object.delete.success",{objectName:e.name}).then(function(e){r.alertSuccess(e)}),$(e),C.catSub=o.subject.findSome(metaRule.subject_categories),C.catObj=o.object.findSome(metaRule.object_categories),C.catAct=o.action.findSome(metaRule.action_categories),e.loader=!1}function a(t){n("moon.model.metadata.object.delete.error",{objectName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.object.delete(e,t,a)}function v(e){function t(t){n("moon.model.metadata.action.delete.success",{actionName:e.name}).then(function(e){r.alertSuccess(e)}),E(e),e.loader=!1}function a(t){n("moon.model.metadata.action.delete.error",{actionName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.action.delete(e,t,a)}function y(){return C.catSub?C.catSub:[]}function j(){return C.catObj?C.catObj:[]}function b(){return C.catAct?C.catAct:[]}function S(e){C.catSub=_.without(C.catSub,e)}function $(e){C.catObj=_.without(C.catObj,e)}function E(e){C.catAct=_.without(C.catAct,e)}function P(e,t){C.metaRule=t,l()}function T(e,t){C.metaRule=t,l()}var C=this;C.metaRule=e.list.metaRule,C.editMode=e.list.editMode,C.typeOfSubject=i.TYPE.SUBJECT,C.typeOfObject=i.TYPE.OBJECT,C.typeOfAction=i.TYPE.ACTION,C.unMapSub=m,C.unMapObj=p,C.unMapAct=f,C.deleteSub=h,C.deleteObj=g,C.deleteAct=v,C.getSubjectCategories=y,C.getObjectCategories=j,C.getActionCategories=b,l();var O={"event:updateMetaRuleFromMetaDataAddSuccess":t.$on("event:updateMetaRuleFromMetaDataAddSuccess",P),"event:deleteMetaDataFromMetaDataAddSuccess":t.$on("event:deleteMetaDataFromMetaDataAddSuccess",T)};for(var M in O)e.$on("$destroy",O[M])}angular.module("moon").directive("moonMetaDataList",e),e.$inject=[],angular.module("moon").controller("moonMetaDataListController",t),t.$inject=["$scope","$rootScope","metaDataService","$translate","alertService","metaRuleService","META_DATA_CST","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metarules/metarules-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{editMode:"=",mappedModel:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a){function i(){return _.table=new o({page:1,count:10,sorting:{name:"asc"}},{total:function(){return _.getMetaRules().length},getData:function(e,t){var o=t.sorting()?n("orderBy")(_.getMetaRules(),t.orderBy()):_.getMetaRules();e.resolve(o.slice((t.page()-1)*t.count(),t.page()*t.count()))},$scope:{$data:{}}}),_.table}function c(){return _.metaRules?_.metaRules:[]}function l(){return _.getMetaRules().length>0}function s(e){e.id===d().id?(_.showDetailValue=!1,_.subject_list=[],_.object_list=[],_.action_list=[]):(_.subject_list=e.subject_categories_values,_.object_list=e.object_categories_values,_.action_list=e.action_categories_values,_.showDetailValue=e)}function u(e){_.edit.modal.$scope.metaRule=e,_.edit.modal.$promise.then(_.edit.modal.show)}function d(){return _.showDetailValue}function m(){return _.subject_list}function p(){return _.object_list}function f(){return _.action_list}function h(){_.map.modal.$scope.model=_.model,_.map.modal.$promise.then(_.map.modal.show)}function g(){_.metaRules=_.model.meta_rules_values,_.table.total(_.getMetaRules().length),_.table.reload()}function v(e,t){_.model=t,g(),_.map.modal.hide()}function y(e){_.unmap.modal.$scope.model=_.model,_.unmap.modal.$scope.metaRule=e,_.unmap.modal.$promise.then(_.unmap.modal.show)}function j(e,t){_.model=t,a.findSomeWithCallback(_.model.meta_rules,function(e){_.model.meta_rules_values=e,g(),_.unmap.modal.hide()})}function b(e){_.unmap.modal.hide()}var _=this;_.table={},_.editMode=e.list.editMode,_.model=e.list.mappedModel,_.metaRules=_.model.meta_rules_values,_.getMetaRules=c,_.hasMetaRules=l,_.showDetail=s,_.getSubjectList=m,_.getObjectList=p,_.getActionlist=f,_.getShowDetailValue=d,_.showDetailValue=!1,_.subject_list=[],_.object_list=[],_.action_list=[],_.edit={modal:r({template:"html/model/edit/metarules/action/metarules-edit.tpl.html",show:!1}),showModal:u},_.map={modal:r({template:"html/model/edit/metarules/action/mapping/metarules-map.tpl.html",show:!1}),showModal:h},_.unmap={modal:r({template:"html/model/edit/metarules/action/mapping/metarules-unmap.tpl.html",show:!1}),showModal:y},function(){i()}();var S={"event:metaRuleMapToModelSuccess":t.$on("event:metaRuleMapToModelSuccess",v),"event:metaRuleUnMappedToModelSuccess":t.$on("event:metaRuleUnMappedToModelSuccess",j),"event:metaRuleUnMappedToModelError":t.$on("event:metaRuleUnMappedToModelError",b)};for(var $ in S)e.$on("$destroy",S[$]);e.$watch("list.editMode",function(e,t){_.showDetailValue=!1})}angular.module("moon").directive("moonMetaRulesList",e),e.$inject=[],angular.module("moon").controller("moonMetaRulesListController",t),t.$inject=["$scope","$rootScope","NgTableParams","$filter","$modal","metaRuleService"]}(),function(){"use strict";function e(e,t,o,n,r,a,i){function c(){s.policiesLoading=!0,r.findAllWithCallback(function(e){s.policies=e,s.policiesLoading=!1})}function l(){function r(n){var r=i.transformOne(n,"pdps");o("moon.policy.map.success",{pdpName:r.name,policyName:s.selectedPolicy.name}).then(function(e){t.alertSuccess(e)}),s.mappingLoading=!1,e.$emit("event:policyMapToPdpSuccess",r)}function c(n){o("moon.policy.map.error",{pdpName:s.pdp.name,policyName:s.selectedPolicy.name}).then(function(e){t.alertError(e)}),s.mappingLoading=!1,e.$emit("event:policyMapToPdpError")}if(n.isInvalid(s.form))n.checkFieldsValidity(s.form);else{s.mappingLoading=!0;var l=angular.copy(s.pdp);l.security_pipeline.push(s.selectedPolicy.id),a.update(l,r,c)}}var s=this;s.pdps=[],s.pdp=e.pdp,s.addPolicyToList=!1,s.map=l,function(){c()}()}angular.module("moon").controller("PolicyMapController",e),e.$inject=["$scope","alertService","$translate","formService","policyService","pdpService","utilService"]}(),function(){"use strict";function e(e,t,o,n,r){function a(){function a(n){t("moon.policy.unmap.success",{pdpName:i.pdp.name,policyName:i.policy.name}).then(function(e){o.alertSuccess(e)}),i.unMappingLoading=!1,e.$emit("event:policyUnMappedToPdpSuccess",r.transformOne(n,"pdps"))}function c(n){t("moon.policy.unmap.error",{pdpName:i.pdp.name,policyName:i.policy.name}).then(function(e){o.alertError(e)}),i.unMappingLoading=!1,e.$emit("event:policyUnMappedToPdpError")}i.unMappingLoading=!0;var l=angular.copy(i.pdp);l.security_pipeline=_.without(l.security_pipeline,i.policy.id),n.update(l,a,c)}var i=this;i.pdp=e.pdp,i.policy=e.policy,i.unMappingLoading=!1,i.unmap=a}angular.module("moon").controller("PolicyUnMapController",e),e.$inject=["$scope","$translate","alertService","pdpService","utilService"]}(),function(){"use strict";function e(e,t,o,n,r){function a(){r.findAllWithCallBack(i)}function i(e){l.pdps=_.filter(e,function(e){return _.isNull(e.keystone_project_id)}),l.pdpsLoading=!1}function c(){function a(n){l.project.pdp=l.selectedPDP,t("moon.project.map.success",{projectName:l.project.name,pdpName:l.selectedPDP.name}).then(function(e){o.alertSuccess(e)}),l.mappingLoading=!1,e.$emit("event:projectMappedSuccess",l.project)}function i(n){t("moon.project.map.error",{projectName:l.project.name,pdpName:l.selectedPDP.name}).then(function(e){o.alertError(e)}),l.mappingLoading=!1,e.$emit("event:projectMappedError",l.project)}n.isInvalid(l.form)?n.checkFieldsValidity(l.form):(l.mappingLoading=!0,r.map(l.selectedPDP,l.project.id,a,i))}var l=this;l.form={},l.project=e.project,l.pdps=[],l.pdpsLoading=!0,l.selectedPDP=null,l.map=c,function(){a()}()}angular.module("moon").controller("ProjectMapController",e),e.$inject=["$scope","$translate","alertService","formService","pdpService"]}(),function(){"use strict";function e(e,t,o,n){function r(){function r(n){t("moon.project.unmap.success",{projectName:a.project.name,pdpName:c}).then(function(e){o.alertSuccess(e)}),a.unMappingLoading=!1,delete a.project.mapping,delete a.project.pdp,e.$emit("event:projectUnmappedSuccess",a.project)}function i(n){t("moon.project.unmap.error",{projectName:a.project.name,pdpName:c}).then(function(e){o.alertError(e)}),a.unMappingLoading=!1,e.$emit("event:projectUnmappedError",a.project)}a.unMappingLoading=!0;var c=a.project.pdp.name;n.unMap(a.project.pdp,r,i)}var a=this;a.project=e.project,a.unMappingLoading=!1,a.unmap=r}angular.module("moon").controller("ProjectUnMapController",e),e.$inject=["$scope","$translate","alertService","pdpService"]}(),function(){"use strict";function e(e,t,o,n){return{data:e(t.MODELS+":model_id",{},{get:{method:"GET"},query:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"},update:{method:"PATCH"}}),findAll:function(){return this.data.query().$promise.then(function(e){return n.transform(e,"models")})},findAllWithCallBack:function(e){return this.data.query().$promise.then(function(t){e(n.transform(t,"models"))})},findOneWithCallback:function(e,t){return this.data.get({model_id:e}).$promise.then(function(e){t(n.transformOne(e,"models"))})},findOneWithMetaRules:function(e){return this.data.get({model_id:e}).$promise.then(function(t){var r=n.transformOne(t,"models");return r.meta_rules.length>0?o.findSomeWithMetaData(r.meta_rules).then(function(t){return r.meta_rules_values=t,r.id=e,r}):(r.meta_rules_values=[],r.id=e),r})},delete:function(e,t,o){delete e.meta_rules_values,this.data.remove({model_id:e.id},e,t,o)},update:function(e,t,o){delete e.meta_rules_values,this.data.update({model_id:e.id},e,t,o)}}}angular.module("moon").factory("modelService",e),e.$inject=["$resource","REST_URI","metaRuleService","utilService"]}(),function(){"use strict";function e(e,t,o,n){return{data:{policy:e(t.POLICIES+":policy_id",{},{query:{method:"GET"},create:{method:"POST"},update:{method:"PATCH"},remove:{method:"DELETE"}})},findAll:function(){return this.data.policy.query().$promise.then(function(e){return o.transform(e,"policies")})},findAllWithCallback:function(e){return this.data.policy.query().$promise.then(function(t){e(o.transform(t,"policies"))})},findOneReturningPromise:function(e){return this.data.policy.get({policy_id:e}).$promise},findSomeWithCallback:function(e,t){var r=this;0===e.length&&t([]);var a=_(e).map(function(e){return r.findOneReturningPromise(e)});n.all(a).then(function(e){t(_(e).map(function(e){return o.transformOne(e,"policies")}))})},findOne:function(e){return this.data.policy.get({policy_id:e}).$promise.then(function(e){return o.transformOne(e,"policies")})},update:function(e,t,o){this.data.policy.update({policy_id:e.id},e,t,o)},delete:function(e,t,o){this.data.policy.remove({policy_id:e.id},e,t,o)}}}angular.module("moon").factory("policyService",e),e.$inject=["$resource","REST_URI","utilService","$q"]}(),function(){"use strict";function e(e,t,o,n){var r={subject:e(t.METADATA.subject+":subject_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}}),object:e(t.METADATA.object+":object_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}}),action:e(t.METADATA.action+":action_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})};return{subject:{findOne:function(e,t){r.subject.get({subject_id:e}).$promise.then(function(e){t(n.transformOne(e,"subject_categories"))})},findOneReturningPromise:function(e){return r.subject.get({subject_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var r=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(r).then(function(e){return _(e).map(function(e){return n.transformOne(e,"subject_categories")})})},findSomeWithCallback:function(e,t){var r=this;0===e.length&&t([]);var a=_(e).map(function(e){return r.findOneReturningPromise(e)});o.all(a).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"subject_categories")}))})},findAll:function(){return r.subject.get().$promise.then(function(e){return n.transform(e,"subject_categories")})},findAllWithCallback:function(e){return r.subject.get().$promise.then(function(t){e(n.transform(t,"subject_categories"))})},delete:function(e,t,o){r.subject.remove({subject_id:e.id},e,t,o)},add:function(e,t,o){r.subject.create({},e,t,o)}},object:{findOne:function(e,t){r.object.get({object_id:e}).$promise.then(function(e){t(n.transformOne(e,"object_categories"))})},findOneReturningPromise:function(e){return r.object.get({object_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var r=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(r).then(function(e){return _(e).map(function(e){return n.transformOne(e,"object_categories")})})},findSomeWithCallback:function(e,t){var r=this;0===e.length&&t([]);var a=_(e).map(function(e){return r.findOneReturningPromise(e)});o.all(a).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"object_categories")}))})},findAll:function(){return r.object.get().$promise.then(function(e){return n.transform(e,"object_categories")})},findAllWithCallback:function(e){return r.object.get().$promise.then(function(t){e(n.transform(t,"object_categories"))})},delete:function(e,t,o){r.object.remove({object_id:e.id},e,t,o)},add:function(e,t,o){r.object.create({},e,t,o)}},action:{findOne:function(e,t){r.action.get({actionId:e}).$promise.then(function(e){t(n.transformOne(e,"action_categories"))})},findOneReturningPromise:function(e){return r.action.get({actionId:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var r=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(r).then(function(e){return _(e).map(function(e){return n.transformOne(e,"action_categories")})})},findSomeWithCallback:function(e,t){var r=this;0===e.length&&t([]);var a=_(e).map(function(e){return r.findOneReturningPromise(e)});o.all(a).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"action_categories")}))})},findAll:function(){return r.action.get().$promise.then(function(e){return n.transform(e,"action_categories")})},findAllWithCallback:function(e){return r.action.get().$promise.then(function(t){e(n.transform(t,"action_categories"))})},delete:function(e,t,o){r.action.remove({action_id:e.id},e,t,o)},add:function(e,t,o){r.action.create({},e,t,o)}}}}angular.module("moon").factory("metaDataService",e),e.$inject=["$resource","REST_URI","$q","utilService"]}(),function(){"use strict";function e(e,t,o,n,r){return{data:e(t.METARULES+":metarule_id",{},{query:{method:"GET"},get:{method:"GET",isArray:!1},update:{method:"PATCH"},create:{method:"POST"},remove:{method:"DELETE"}}),findAll:function(){return this.data.query().$promise.then(function(e){return r.transform(e,"meta_rules")})},findAllWithCallback:function(e){this.data.query().$promise.then(function(t){e(r.transform(t,"meta_rules"))})},findSomeWithMetaData:function(e){var t=this;if(0===e.length)return[];var o=_(e).map(function(e){return t.findOneReturningPromise(e)});return n.all(o).then(function(e){return _(e).map(function(e){var o=r.transformOne(e,"meta_rules");return o=t.findMetaDataFromMetaRule(o)})})},findSomeWithCallback:function(e,t){var o=this;if(0===e.length)return[];var a=_(e).map(function(e){return o.findOneReturningPromise(e)});return n.all(a).then(function(e){t(_(e).map(function(e){return r.transformOne(e,"meta_rules")}))})},findOneReturningPromise:function(e){return this.data.get({metarule_id:e}).$promise},findOne:function(e){return this.data.get({metarule_id:e}).$promise.then(function(e){return r.transformOne(e,"meta_rules")})},findOneWithCallback:function(e,t){this.data.get({metarule_id:e}).$promise.then(function(e){t(r.transformOne(e,"meta_rules"))})},findOneWithMetaData:function(e){var t=this;return this.data.get({metarule_id:e}).$promise.then(function(e){var o=r.transformOne(e,"meta_rules");return o=t.findMetaDataFromMetaRule(o)})},findMetaDataFromMetaRule:function(e){return e.subject_categories.length>0?o.subject.findSome(e.subject_categories).then(function(t){e.subject_categories_values=t}):e.subject_categories_values=[],e.object_categories.length>0?o.object.findSome(e.object_categories).then(function(t){e.object_categories_values=t}):e.object_categories_values=[],e.action_categories.length>0?o.action.findSome(e.action_categories).then(function(t){e.action_categories_values=t}):e.action_categories_values=[],e},delete:function(e,t,o){this.data.remove({metarule_id:e.id},e,t,o)},update:function(e,t,o){delete e.subject_categories_values,delete e.object_categories_values,delete e.action_categories_values,this.data.update({metarule_id:e.id},e,t,o)}}}angular.module("moon").factory("metaRuleService",e),e.$inject=["$resource","REST_URI","metaDataService","$q","utilService"]}(),function(){"use strict";function e(e,t){function o(e,t){n.metaRule=t}var n=this;n.metaRule=e.metaRule;var r={"event:metaRuleBasicUpdatedSuccess":t.$on("event:metaRuleBasicUpdatedSuccess",o)};for(var a in r)e.$on("$destroy",r[a])}angular.module("moon").controller("MetaRulesEditController",e),e.$inject=["$scope","$rootScope"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metarules/action/metarules-edit-basic.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{metaRule:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a){function i(){function i(t){var o=a.transformOne(t,"meta_rules");r("moon.model.metarules.edit.basic.success",{metaRuleName:o.name}).then(function(e){n.alertSuccess(e)}),l.loading=!1,e.$emit("event:metaRuleBasicUpdatedSuccess",o)}function c(e){r("moon.model.edit.basic.error",{metaRuleName:l.metaRule.name}).then(function(e){n.alertError(e)}),l.loading=!1}o.isInvalid(l.form)?o.checkFieldsValidity(l.form):(l.loading=!0,t.update(l.metaRuleToEdit,i,c))}function c(){l.metaRuleToEdit=angular.copy(l.metaRule)}var l=this;l.editMetaRule=i,l.init=c,l.form={},function(){l.metaRule=e.edit.metaRule,l.metaRuleToEdit=angular.copy(l.metaRule)}()}angular.module("moon").directive("moonMetaRulesEditBasic",e),e.$inject=[],angular.module("moon").controller("moonMetaRulesEditBasicController",t),t.$inject=["$scope","metaRuleService","formService","alertService","$translate","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/assignments/assignments-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{policy:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a,i,c,l,s,u){function d(){m(),p(),f()}function m(){D.loadingSub=!0,o.subject.findAllFromPolicyWithCallback(D.policy.id,function(e){console.log("subjects"),console.log(e),D.subjects=e,D.loadingSub=!1})}function p(){D.loadingObj=!0,o.object.findAllFromPolicyWithCallback(D.policy.id,function(e){console.log("objects"),console.log(e),D.objects=e,D.loadingObj=!1})}function f(){D.loadingAct=!0,o.action.findAllFromPolicyWithCallback(D.policy.id,function(e){console.log("actions"),console.log(e),D.actions=e,D.loadingAct=!1})}function h(e,t){function o(t){e.callPerimeterInProgress=!1,e.perimeter=t}if(_.has(e,"perimeter"))return e.perimeter;if(!_.has(e,"callPerimeterInProgress"))switch(e.callPerimeterInProgress=!0,t){case i.TYPE.SUBJECT:s.subject.findOneFromPolicyWithCallback(D.policy.id,e.subject_id,o);break;case i.TYPE.OBJECT:s.object.findOneFromPolicyWithCallback(D.policy.id,e.object_id,o);break;case i.TYPE.ACTION:s.action.findOneFromPolicyWithCallback(D.policy.id,e.action_id,o)}return!1}function g(e,t){function o(t){e.callCategoryInProgress=!1,e.category=t}if(_.has(e,"category"))return e.category;if(!_.has(e,"callCategoryInProgress"))switch(e.callCategoryInProgress=!0,t){case i.TYPE.SUBJECT:l.subject.findOne(e.subject_cat_id,o);break;case i.TYPE.OBJECT:l.object.findOne(e.object_cat_id,o);break;case i.TYPE.ACTION:l.action.findOne(e.action_cat_id,o)}return!1}function v(e,t,o){function n(o){t.assignments_value[e].callDataInProgress=!1,t.assignments_value[e].data=o}if(_.has(t,"assignments_value")||(t.assignments_value=Array.apply(null,new Array(t.assignments.length)).map(function(){return{data:{}}})),_.has(t.assignments_value[e],"callDataInProgress")&&!t.assignments_value[e].callDataInProgress)return t.assignments_value[e].data;if(!_.has(t.assignments_value[e],"callDataInProgress"))switch(t.assignments_value[e].callDataInProgress=!0,o){case i.TYPE.SUBJECT:u.subject.data.findOne(D.policy.id,t.category_id,t.assignments[e],n);break;case i.TYPE.OBJECT:u.object.data.findOne(D.policy.id,t.category_id,t.assignments[e],n);break;case i.TYPE.ACTION:u.action.data.findOne(D.policy.id,t.category_id,t.assignments[e],n)}return!1}function y(e){function t(t){n("moon.policy.metarules.update.success",{policyName:D.policy.name}).then(function(e){r.alertSuccess(e)}),D.policy=a.findDataFromPolicy(c.transformOne(t,"meta_rules")),d(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:D.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(D.policy);i.subject_categories=_.without(i.subject_categories,e.id),a.update(i,t,o)}function j(e){function t(t){n("moon.policy.metarules.update.success",{policyName:D.policy.name}).then(function(e){r.alertSuccess(e)}),D.policy=a.findDataFromPolicy(c.transformOne(t,"meta_rules")),d(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:D.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(D.policy);i.object_categories=_.without(i.object_categories,e.id),a.update(i,t,o)}function b(e){function t(t){n("moon.policy.metarules.update.success",{policyName:D.policy.name}).then(function(e){r.alertSuccess(e)}),D.policy=a.findDataFromPolicy(c.transformOne(t,"meta_rules")),d(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:D.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(D.policy);i.action_categories=_.without(i.action_categories,e.id),a.update(i,t,o)}function S(e){function t(t){n("moon.policy.perimeter.subject.delete.success",{ +subjectName:e.name}).then(function(e){r.alertSuccess(e)}),O(e),e.loader=!1}function a(t){n("moon.policy.perimeter.subject.delete.error",{subjectName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.subject.delete(e,t,a)}function $(e){function t(t){n("moon.policy.perimeter.object.delete.success",{objectName:e.name}).then(function(e){r.alertSuccess(e)}),M(e),e.loader=!1}function a(t){n("moon.policy.perimeter.object.delete.error",{objectName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.object.delete(e,t,a)}function E(e){function t(t){n("moon.policy.perimeter.action.delete.success",{actionName:e.name}).then(function(e){r.alertSuccess(e)}),A(e),e.loader=!1}function a(t){n("moon.policy.perimeter.action.delete.error",{actionName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.action.delete(e,t,a)}function P(){return D.subjects?D.subjects:[]}function T(){return D.objects?D.objects:[]}function C(){return D.actions?D.actions:[]}function O(e){D.subjects=_.without(D.subjects,e)}function M(e){D.objects=_.without(D.objects,e)}function A(e){D.actions=_.without(D.actions,e)}function R(e,t){D.policy=t,d()}var D=this;D.policy=e.list.policy,D.editMode=e.list.editMode,D.typeOfSubject=i.TYPE.SUBJECT,D.typeOfObject=i.TYPE.OBJECT,D.typeOfAction=i.TYPE.ACTION,D.unMapSub=y,D.unMapObj=j,D.unMapAct=b,D.deleteSub=S,D.deleteObj=$,D.deleteAct=E,D.getSubjects=P,D.getObjects=T,D.getActions=C,D.getCategoryFromAssignment=g,D.getPerimeterFromAssignment=h,D.getDataFromAssignmentsIndex=v,d();var N={"event:deleteDataFromDataAddSuccess":t.$on("event:deleteDataFromDataAddSuccess",R)};for(var w in N)e.$on("$destroy",N[w])}angular.module("moon").directive("moonAssignmentsList",e),e.$inject=[],angular.module("moon").controller("moonAssignmentsListController",t),t.$inject=["$scope","$rootScope","assignmentService","$translate","alertService","policyService","ASSIGNMENTS_CST","utilService","metaDataService","perimeterService","dataService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/data/data-edit.tpl.html",bindToController:!0,controller:t,controllerAs:"edit",scope:{metaDataType:"=",metaRule:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a,i,c){function l(){function e(e){g.list=e}switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.findAllWithCallback(e);break;case o.TYPE.OBJECT:t.object.findAllWithCallback(e);break;case o.TYPE.ACTION:t.action.findAllWithCallback(e);break;default:g.list=[]}}function s(){function t(t){r("moon.model.metarules.update.success",{metaRuleName:l.name}).then(function(e){n.alertSuccess(e)}),l=c.transformOne(t,"meta_rules"),e.$emit("event:updateMetaRuleFromMetaDataAddSuccess",l),f()}function a(e){r("moon.model.metarules.update.error",{metaRuleName:l.name,reason:e.message}).then(function(e){n.alertError(e)}),f()}if(g.selectedMetaData){var l=g.metaRule;switch(g.metaDataType){case o.TYPE.SUBJECT:l.subject_categories.push(g.selectedMetaData.id);break;case o.TYPE.OBJECT:l.object_categories.push(g.selectedMetaData.id);break;case o.TYPE.ACTION:l.action_categories.push(g.selectedMetaData.id)}i.update(l,t,a)}}function u(){function e(e){var t={};switch(g.metaDataType){case o.TYPE.SUBJECT:t=c.transformOne(e,"subject_categories");break;case o.TYPE.OBJECT:t=c.transformOne(e,"object_categories");break;case o.TYPE.ACTION:t=c.transformOne(e,"action_categories")}r("moon.model.metadata.edit.create.success",{name:t.name}).then(function(e){n.alertSuccess(e)}),f(),g.list.push(t),h()}function i(e){r("moon.model.metadata.edit.create.error",{name:l.name}).then(function(e){n.alertError(e)}),f()}if(a.isInvalid(g.form))a.checkFieldsValidity(g.form);else{p();var l=angular.copy(g.metaData);switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.add(l,e,i);break;case o.TYPE.OBJECT:t.object.add(l,e,i);break;case o.TYPE.ACTION:t.action.add(l,e,i)}}}function d(){function a(t){r("moon.model.metadata.edit.delete.success",{name:s.name}).then(function(e){n.alertSuccess(e)}),i.findOneWithMetaData(g.metaRule.id).then(function(t){g.metaRule=t,m(),l(),f(),e.$emit("event:deleteMetaDataFromMetaDataAddSuccess",g.metaRule)})}function c(e){r("moon.model.metadata.edit.delete.error",{name:s.name}).then(function(e){n.alertError(e)}),f()}if(g.selectedMetaData){p();var s=angular.copy(g.selectedMetaData);switch(g.metaDataType){case o.TYPE.SUBJECT:t.subject.delete(s,a,c);break;case o.TYPE.OBJECT:t.object.delete(s,a,c);break;case o.TYPE.ACTION:t.action.delete(s,a,c)}}}function m(){delete g.selectedMetaData}function p(){g.loading=!0}function f(){g.loading=!1}function h(){g.fromList=!0}var g=this;g.metaDataType=e.edit.metaDataType,g.metaRule=e.edit.metaRule,g.fromList=!0,g.laoading=!1,g.form={},g.metaData={name:null,description:null},g.list=[],g.create=u,g.addToMetaRule=s,g.deleteMetaData=d,l()}angular.module("moon").directive("moonDataEdit",e),e.$inject=[],angular.module("moon").controller("moonDataEditController",t),t.$inject=["$scope","metaDataService","DATA_CST","alertService","$translate","formService","policyService","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/data/data-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{policy:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a,i,c,l){function s(){u(),d(),m()}function u(){O.loadingSub=!0,o.subject.findAllFromPolicyWithCallback(O.policy.id,function(e){console.log("subjects"),console.log(e),O.subjects=e,O.loadingSub=!1})}function d(){O.loadingObj=!0,o.object.findAllFromPolicyWithCallback(O.policy.id,function(e){console.log("objects"),console.log(e),O.objects=e,O.loadingObj=!1})}function m(){O.loadingAct=!0,o.action.findAllFromPolicyWithCallback(O.policy.id,function(e){console.log("actions"),console.log(e),O.actions=e,O.loadingAct=!1})}function p(e,t){function o(t){e.callCategoryInProgress=!1,e.category=t}if(_.has(e,"category"))return e.category;if(!_.has(e,"callCategoryInProgress"))switch(e.callCategoryInProgress=!0,t){case i.TYPE.SUBJECT:l.subject.findOne(e.category_id,o);break;case i.TYPE.OBJECT:l.object.findOne(e.category_id,o);break;case i.TYPE.ACTION:l.action.findOne(e.category_id,o)}return!1}function f(e){function t(t){n("moon.policy.metarules.update.success",{policyName:O.policy.name}).then(function(e){r.alertSuccess(e)}),O.policy=a.findDataFromPolicy(c.transformOne(t,"meta_rules")),s(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:O.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(O.policy);i.subject_categories=_.without(i.subject_categories,e.id),a.update(i,t,o)}function h(e){function t(t){n("moon.policy.metarules.update.success",{policyName:O.policy.name}).then(function(e){r.alertSuccess(e)}),O.policy=a.findDataFromPolicy(c.transformOne(t,"meta_rules")),s(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:O.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(O.policy);i.object_categories=_.without(i.object_categories,e.id),a.update(i,t,o)}function g(e){function t(t){n("moon.policy.metarules.update.success",{policyName:O.policy.name}).then(function(e){r.alertSuccess(e)}),O.policy=a.findDataFromPolicy(c.transformOne(t,"meta_rules")),s(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:O.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(O.policy);i.action_categories=_.without(i.action_categories,e.id),a.update(i,t,o)}function v(e){function t(t){n("moon.policy.perimeter.subject.delete.success",{subjectName:e.name}).then(function(e){r.alertSuccess(e)}),E(e),e.loader=!1}function a(t){n("moon.policy.perimeter.subject.delete.error",{subjectName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.subject.delete(e,t,a)}function y(e){function t(t){n("moon.policy.perimeter.object.delete.success",{objectName:e.name}).then(function(e){r.alertSuccess(e)}),P(e),e.loader=!1}function a(t){n("moon.policy.perimeter.object.delete.error",{objectName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.object.delete(e,t,a)}function j(e){function t(t){n("moon.policy.perimeter.action.delete.success",{actionName:e.name}).then(function(e){r.alertSuccess(e)}),T(e),e.loader=!1}function a(t){n("moon.policy.perimeter.action.delete.error",{actionName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.action.delete(e,t,a)}function b(){return O.subjects?O.subjects:[]}function S(){return O.objects?O.objects:[]}function $(){return O.actions?O.actions:[]}function E(e){O.subjects=_.without(O.subjects,e)}function P(e){O.objects=_.without(O.objects,e)}function T(e){O.actions=_.without(O.actions,e)}function C(e,t){O.policy=t,s()}var O=this;O.policy=e.list.policy,O.editMode=e.list.editMode,O.typeOfSubject=i.TYPE.SUBJECT,O.typeOfObject=i.TYPE.OBJECT,O.typeOfAction=i.TYPE.ACTION,O.unMapSub=f,O.unMapObj=h,O.unMapAct=g,O.deleteSub=v,O.deleteObj=y,O.deleteAct=j,O.getSubjects=b,O.getObjects=S,O.getActions=$,O.getCategoryFromData=p,s();var M={"event:deleteDataFromDataAddSuccess":t.$on("event:deleteDataFromDataAddSuccess",C)};for(var A in M)e.$on("$destroy",M[A])}angular.module("moon").directive("moonDataList",e),e.$inject=[],angular.module("moon").controller("moonDataListController",t),t.$inject=["$scope","$rootScope","dataService","$translate","alertService","policyService","DATA_CST","utilService","metaDataService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/perimeter/perimeter-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{policy:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a,i,c){function l(){s(),u(),d()}function s(){T.loadingSub=!0,o.subject.findAllFromPolicyWithCallback(T.policy.id,function(e){T.subjects=e,T.loadingSub=!1})}function u(){T.loadingObj=!0,o.object.findAllFromPolicyWithCallback(T.policy.id,function(e){console.log("objects"),console.log(e),T.objects=e,T.loadingObj=!1})}function d(){T.loadingAct=!0,o.action.findAllFromPolicyWithCallback(T.policy.id,function(e){console.log("actions"),console.log(e),T.actions=e,T.loadingAct=!1})}function m(e){function t(t){n("moon.policy.metarules.update.success",{policyName:T.policy.name}).then(function(e){r.alertSuccess(e)}),T.policy=a.findPerimeterFromPolicy(c.transformOne(t,"meta_rules")),l(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:T.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(T.policy);i.subject_categories=_.without(i.subject_categories,e.id),a.update(i,t,o)}function p(e){function t(t){n("moon.policy.metarules.update.success",{policyName:T.policy.name}).then(function(e){r.alertSuccess(e)}),T.policy=a.findPerimeterFromPolicy(c.transformOne(t,"meta_rules")),l(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:T.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(T.policy);i.object_categories=_.without(i.object_categories,e.id),a.update(i,t,o)}function f(e){function t(t){n("moon.policy.metarules.update.success",{policyName:T.policy.name}).then(function(e){r.alertSuccess(e)}),T.policy=a.findPerimeterFromPolicy(c.transformOne(t,"meta_rules")),l(),e.loader=!1}function o(t){n("moon.policy.metarules.update.error",{policyName:T.policy.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0;var i=angular.copy(T.policy);i.action_categories=_.without(i.action_categories,e.id),a.update(i,t,o)}function h(e){function t(t){n("moon.policy.perimeter.subject.delete.success",{subjectName:e.name}).then(function(e){r.alertSuccess(e)}),S(e),e.loader=!1}function a(t){n("moon.policy.perimeter.subject.delete.error",{subjectName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.subject.delete(e,t,a)}function g(e){function t(t){n("moon.policy.perimeter.object.delete.success",{objectName:e.name}).then(function(e){r.alertSuccess(e)}),$(e),e.loader=!1}function a(t){n("moon.policy.perimeter.object.delete.error",{objectName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.object.delete(e,t,a)}function v(e){function t(t){n("moon.policy.perimeter.action.delete.success",{actionName:e.name}).then(function(e){r.alertSuccess(e)}),E(e),e.loader=!1}function a(t){n("moon.policy.perimeter.action.delete.error",{actionName:e.name,reason:t.message}).then(function(e){r.alertError(e)}),e.loader=!1}e.loader=!0,o.action.delete(e,t,a)}function y(){return T.subjects?T.subjects:[]}function j(){return T.objects?T.objects:[]}function b(){return T.actions?T.actions:[]}function S(e){T.subjects=_.without(T.subjects,e)}function $(e){T.objects=_.without(T.objects,e)}function E(e){T.actions=_.without(T.actions,e)}function P(e,t){T.policy=t,l()}var T=this;T.policy=e.list.policy,T.editMode=e.list.editMode,T.typeOfSubject=i.TYPE.SUBJECT,T.typeOfObject=i.TYPE.OBJECT,T.typeOfAction=i.TYPE.ACTION,T.unMapSub=m,T.unMapObj=p,T.unMapAct=f,T.deleteSub=h,T.deleteObj=g,T.deleteAct=v,T.getSubjects=y,T.getObjects=j,T.getActions=b,l();var C={"event:deletePerimeterFromPerimeterAddSuccess":t.$on("event:deletePerimeterFromPerimeterAddSuccess",P)};for(var O in C)e.$on("$destroy",C[O])}angular.module("moon").directive("moonPerimeterList",e),e.$inject=[],angular.module("moon").controller("moonPerimeterListController",t),t.$inject=["$scope","$rootScope","perimeterService","$translate","alertService","policyService","PERIMETER_CST","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/policy/edit/parameter/rules/rules-list.tpl.html",bindToController:!0,controller:t,controllerAs:"list",scope:{policy:"=",editMode:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r){function a(){n.findAllFromPolicyWithCallback(h.policy.id,function(e){console.log("rules"),console.log(e),h.rules=e,h.loadingRules=!1,f()})}function i(){return h.table=new e({page:1,count:10,sorting:{name:"asc"}},{total:function(){return h.getRules().length},getData:function(e,o){var n=o.sorting()?t("orderBy")(h.getRules(),o.orderBy()):h.getRules();e.resolve(n.slice((o.page()-1)*o.count(),o.page()*o.count()))},$scope:{$data:{}}}),h.table}function c(e){return _.has(e,"meta_rule")?e.meta_rule:(_.has(e,"callMetaRuleInProgress")||(e.callMetaRuleInProgress=!0,o.findOneWithCallback(e.meta_rule_id,function(t){e.callMetaRuleInProgress=!1,e.meta_rule=t})),!1)}function l(e,t){if(_.has(t,"rule_value")||(t.rule_value=Array.apply(null,new Array(t.rule.length)).map(function(){return{category:{}}})),_.has(t.rule_value[e],"callCategoryInProgress")&&!t.rule_value[e].callCategoryInProgress)return t.rule_value[e].category;if(!_.has(t.rule_value[e],"callCategoryInProgress")){t.rule_value[e].callCategoryInProgress=!0;var o=0;h.isRuleIndexSubjectCategory(e,t)?(o=t.meta_rule.subject_categories[e],r.subject.data.findOne(h.policy.id,o,t.rule[e],function(o){t.rule_value[e].callCategoryInProgress=!1,t.rule_value[e].category=o})):h.isRuleIndexObjectCategory(e,t)?(o=t.meta_rule.object_categories[e-t.meta_rule.subject_categories.length],r.object.data.findOne(h.policy.id,o,t.rule[e],function(o){t.rule_value[e].callCategoryInProgress=!1,t.rule_value[e].category=o})):h.isRuleIndexActionCategory(e,t)?(o=t.meta_rule.action_categories[e-t.meta_rule.subject_categories.length-t.meta_rule.object_categories.length],r.action.data.findOne(h.policy.id,o,t.rule[e],function(o){t.rule_value[e].callCategoryInProgress=!1,t.rule_value[e].category=o})):(t.rule_value[e].callCategoryInProgress=!1,t.rule_value[e].category={name:"ERROR"})}return!1}function s(e,t){return e+1<=t.meta_rule.subject_categories.length}function u(e,t){var o=e+1;return t.meta_rule.subject_categories.length0}function f(){h.table.total(h.rules.length),h.table.reload()}var h=this;h.rules=[],h.loadingRules=!0,h.table={},h.getRules=m,h.hasRules=p,h.refreshRules=f,h.getMetaRuleFromRule=c,h.getCategoryFromRuleIndex=l,h.isRuleIndexSubjectCategory=s,h.isRuleIndexObjectCategory=u,h.isRuleIndexActionCategory=d,function(){i(),a()}()}angular.module("moon").directive("moonRulesList",e),e.$inject=[],angular.module("moon").controller("moonRulesListController",t),t.$inject=["NgTableParams","$filter","metaRuleService","ruleService","dataService"]}(),function(){"use strict";function e(e,t,o){var n={subject:{policy:e(t.POLICIES+":policy_id/subject_assignments/:subject_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},object:{policy:e(t.POLICIES+":policy_id/object_assignments/:object_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})},action:{policy:e(t.POLICIES+":policy_id/action_assignments/:action_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})}};return{subject:{findAllFromPolicyWithCallback:function(e,t){n.subject.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e,"subject_assignments"))})}},object:{findAllFromPolicyWithCallback:function(e,t){n.object.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e,"object_assignments"))})}},action:{findAllFromPolicyWithCallback:function(e,t){n.action.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e,"action_assignments"))})}}}}angular.module("moon").factory("assignmentService",e),e.$inject=["$resource","REST_URI","utilService"]}(),function(){"use strict";function e(e,t,o){var n={subject:{policy:e(t.POLICIES+":policy_id/subject_data/:subject_id/:data_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},object:{policy:e(t.POLICIES+":policy_id/object_data/:object_id/:data_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})},action:{policy:e(t.POLICIES+":policy_id/action_data/:action_id/:data_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})}};return{subject:{findAllFromPolicyWithCallback:function(e,t){n.subject.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e.subject_data[0],"data"))})},delete:function(e,t,o){n.subject.perimeter.remove({subject_id:e.id},e,t,o)},add:function(e,t,o){n.subject.perimeter.create({},e,t,o)},data:{findOne:function(e,t,r,a){n.subject.policy.get({policy_id:e,subject_id:t,data_id:r}).$promise.then(function(e){a(e.subject_data[0]?o.transformOne(e.subject_data[0],"data"):{})})}}},object:{findAllFromPolicyWithCallback:function(e,t){n.object.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e.object_data[0],"data"))})},delete:function(e,t,o){n.object.perimeter.remove({object_id:e.id},e,t,o)},add:function(e,t,o){n.object.perimeter.create({},e,t,o)},data:{findOne:function(e,t,r,a){n.object.policy.get({policy_id:e,object_id:t,data_id:r}).$promise.then(function(e){a(e.object_data[0]?o.transformOne(e.object_data[0],"data"):{})})}}},action:{findAllFromPolicyWithCallback:function(e,t){n.action.policy.get({policy_id:e}).$promise.then(function(e){t(o.transform(e.action_data[0],"data"))})},delete:function(e,t,o){n.action.perimeter.remove({action_id:e.id},e,t,o)},add:function(e,t,o){n.action.perimeter.create({},e,t,o)},data:{findOne:function(e,t,r,a){n.action.policy.get({policy_id:e,action_id:t,data_id:r}).$promise.then(function(e){a(e.action_data[0]?o.transformOne(e.action_data[0],"data"):{})})}}}}}angular.module("moon").factory("dataService",e),e.$inject=["$resource","REST_URI","utilService"]}(),function(){"use strict";function e(e,t,o,n){var r={subject:{perimeter:e(t.PERIMETERS.subject+":subject_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}}),policy:e(t.POLICIES+":policy_id/subjects/:subject_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},object:{perimeter:e(t.PERIMETERS.object+":object_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}}),policy:e(t.POLICIES+":policy_id/objects/:object_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})},action:{perimeter:e(t.PERIMETERS.action+":action_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}}),policy:e(t.POLICIES+":policy_id/actions/:action_id",{},{get:{method:"GET",isArray:!1},create:{method:"POST"},remove:{method:"DELETE"}})}};return{subject:{findOne:function(e,t){r.subject.perimeter.get({subject_id:e}).$promise.then(function(e){t(n.transformOne(e,"subjects"))})},findOneReturningPromise:function(e){return r.subject.perimeter.get({subject_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var r=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(r).then(function(e){return _(e).map(function(e){return n.transformOne(e,"subjects")})})},findAllFromPolicyWithCallback:function(e,t){r.subject.policy.get({policy_id:e}).$promise.then(function(e){t(n.transform(e,"subjects"))})},findOneFromPolicyWithCallback:function(e,t,o){r.subject.policy.get({policy_id:e,subject_id:t}).$promise.then(function(e){o(n.transformOne(e,"subjects"))})},findAll:function(){return r.subject.perimeter.get().$promise.then(function(e){return n.transform(e,"subjects")})},findAllWithCallback:function(e){return r.subject.perimeter.get().$promise.then(function(t){e(n.transform(t,"subjects"))})},delete:function(e,t,o){r.subject.perimeter.remove({subject_id:e.id},e,t,o)},add:function(e,t,o){r.subject.perimeter.create({},e,t,o)}},object:{findOne:function(e,t){r.object.perimeter.get({object_id:e}).$promise.then(function(e){t(n.transformOne(e,"objects"))})},findOneReturningPromise:function(e){return r.object.perimeter.get({object_id:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var r=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(r).then(function(e){return _(e).map(function(e){return n.transformOne(e,"objects")})})},findSomeWithCallback:function(e,t){var r=this;0===e.length&&t([]);var a=_(e).map(function(e){return r.findOneReturningPromise(e)});o.all(a).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"objects")}))})},findAll:function(){return r.object.perimeter.get().$promise.then(function(e){return n.transform(e,"objects")})},findAllFromPolicyWithCallback:function(e,t){r.object.policy.get({policy_id:e}).$promise.then(function(e){t(n.transform(e,"objects"))})},findOneFromPolicyWithCallback:function(e,t,o){r.object.policy.get({policy_id:e,object_id:t}).$promise.then(function(e){o(n.transformOne(e,"objects"))})},findAllWithCallback:function(e){return r.object.perimeter.get().$promise.then(function(t){e(n.transform(t,"objects"))})},delete:function(e,t,o){r.object.perimeter.remove({object_id:e.id},e,t,o)},add:function(e,t,o){r.object.perimeter.create({},e,t,o)}},action:{findOne:function(e,t){r.action.perimeter.get({actionId:e}).$promise.then(function(e){t(n.transformOne(e,"actions"))})},findOneReturningPromise:function(e){return r.action.perimeter.get({actionId:e}).$promise},findSome:function(e){var t=this;if(0===e.length)return[];var r=_(e).map(function(e){return t.findOneReturningPromise(e)});return o.all(r).then(function(e){return _(e).map(function(e){return n.transformOne(e,"actions")})})},findSomeWithCallback:function(e,t){var r=this;0===e.length&&t([]);var a=_(e).map(function(e){return r.findOneReturningPromise(e)});o.all(a).then(function(e){t(_(e).map(function(e){return n.transformOne(e,"actions")}))})},findAll:function(){return r.action.perimeter.get().$promise.then(function(e){return n.transform(e,"actions")})},findAllFromPolicyWithCallback:function(e,t){r.action.policy.get({policy_id:e}).$promise.then(function(e){t(n.transform(e,"actions"))})},findOneFromPolicyWithCallback:function(e,t,o){r.action.policy.get({policy_id:e,action_id:t}).$promise.then(function(e){o(n.transformOne(e,"actions"))})},findAllWithCallback:function(e){return r.action.perimeter.get().$promise.then(function(t){e(n.transform(t,"actions"))})},delete:function(e,t,o){r.action.perimeter.remove({action_id:e.id},e,t,o)},add:function(e,t,o){r.action.perimeter.create({},e,t,o)}}}}angular.module("moon").factory("perimeterService",e),e.$inject=["$resource","REST_URI","$q","utilService"]}(),function(){"use strict";function e(e,t,o){return{data:{policy:e(t.POLICIES+":policy_id/rules/:rule_id",{},{get:{method:"GET"},create:{method:"POST"},remove:{method:"DELETE"}})},findAllFromPolicyWithCallback:function(e,t){this.data.policy.get({policy_id:e}).$promise.then(function(e){console.log("ruleService - findAllFromPolicyWithCallback()"),console.log(e);var n=e.rules;console.log(JSON.stringify(n)),t(o.transform(n,"rules"))})}}}angular.module("moon").factory("ruleService",e),e.$inject=["$resource","REST_URI","utilService"]}(),function(){"use strict";function e(){return{templateUrl:"html/model/edit/metarules/action/mapping/metarules-add.tpl.html",bindToController:!0,controller:t,controllerAs:"add",scope:{metaRules:"="},restrict:"E",replace:!0}}function t(e,t,o,n,r,a){function i(){function i(t){var r=a.transformOne(t,"meta_rules");n("moon.model.metarules.add.success",{metaRuleName:r.name}).then(function(e){o.alertSuccess(e)}),c.loading=!1,e.$emit("event:metaRuleCreatedSuccess",r)}function l(t){n("moon.model.metarules.add.error",{metaRuleName:c.metaRule.name}).then(function(e){o.alertError(e)}),c.loading=!1,e.$emit("event:metaRuleCreatedError",c.project)}r.isInvalid(c.form)?r.checkFieldsValidity(c.form):(c.loading=!0,t.data.create({},c.metaRule,i,l))}var c=this;c.laoading=!1,c.form={},c.metaRule={name:null,description:null,subject_categories:[],object_categories:[],action_categories:[]},c.create=i}angular.module("moon").directive("moonMetaRulesAdd",e),e.$inject=[],angular.module("moon").controller("moonMetaRulesAddController",t),t.$inject=["$scope","metaRuleService","alertService","$translate","formService","utilService"]}(),function(){"use strict";function e(e,t,o,n,r,a,i,c){function l(){h.metaRulesLoading=!0,a.findAllWithCallback(function(e){h.metaRules=e,h.metaRulesLoading=!1})}function s(){function t(t){var r=c.transformOne(t,"models");a.findSomeWithMetaData(r.meta_rules).then(function(t){r.meta_rules_values=t,n("moon.model.metarules.map.success",{modelName:r.name,metaRuleName:h.selectedMetaRule.name}).then(function(e){o.alertSuccess(e)}),h.mappingLoading=!1,e.$emit("event:metaRuleMapToModelSuccess",r)})}function l(e){n("moon.model.metarules.map.error",{modelName:h.model.name,metaRuleName:h.selectedMetaRule.name}).then(function(e){o.alertError(e)}),h.mappingLoading=!1}if(r.isInvalid(h.form))r.checkFieldsValidity(h.form);else{h.mappingLoading=!0;var s=angular.copy(h.model);s.meta_rules.push(h.selectedMetaRule.id),i.update(s,t,l)}}function u(){delete h.selectedMetaRule}function d(){function t(t){n("moon.model.metarules.delete.success",{metaRuleName:i.name}).then(function(e){o.alertSuccess(e)}),u(),h.mappingLoading=!1,l(),e.$emit("event:deleteMetaRule",i)}function r(e){n("moon.model.metarules.delete.error",{metaRuleName:i.name}).then(function(e){o.alertError(e)}),h.mappingLoading=!1}if(h.selectedMetaRule){h.mappingLoading=!0;var i=angular.copy(h.selectedMetaRule);a.delete(i,t,r)}}function m(e,t){h.metaRules.push(t),f()}function p(e){}function f(){h.addMetaRuleToList=!1}var h=this;h.metaRules=[],h.model=e.model,h.addMetaRuleToList=!1,h.mapToModel=s,h.deleteMetaRule=d,function(){l()}();var g={"event:metaRuleCreatedSuccess":t.$on("event:metaRuleCreatedSuccess",m),"event:metaRuleCreatedError":t.$on("event:metaRuleCreatedError",p)};for(var v in g)e.$on("$destroy",g[v])}angular.module("moon").controller("moonMetaRulesMapController",e),e.$inject=["$scope","$rootScope","alertService","$translate","formService","metaRuleService","modelService","utilService"]}(),function(){"use strict";function e(e,t,o,n){function r(){function r(n){t("moon.model.metarules.unmap.success",{modelName:a.model.name,metaRuleName:a.metaRule.name}).then(function(e){o.alertSuccess(e)}),a.unMappingLoading=!1,e.$emit("event:metaRuleUnMappedToModelSuccess",c)}function i(n){t("moon.model.metarules.unmap.error",{modelName:a.model.name,metaRuleName:a.metaRule.name}).then(function(e){o.alertError(e)}),a.unMappingLoading=!1,e.$emit("event:metaRuleUnMappedToModelError")}a.unMappingLoading=!0;var c=angular.copy(a.model);c.meta_rules=_.without(c.meta_rules,a.metaRule.id),n.update(c,r,i)}var a=this;a.model=e.model,a.metaRule=e.metaRule,a.unMappingLoading=!1,a.unmap=r}angular.module("moon").controller("MetaRulesUnMapController",e),e.$inject=["$scope","$translate","alertService","modelService"]}(); \ No newline at end of file diff --git a/moonv4/moon_gui/delivery/js/modules.js b/moonv4/moon_gui/delivery/js/modules.js new file mode 100644 index 00000000..a445cb87 --- /dev/null +++ b/moonv4/moon_gui/delivery/js/modules.js @@ -0,0 +1,19 @@ +function require(e,t,n){var i=require.resolve(e);if(null==i){n=n||e,t=t||"root";var r=new Error('Failed to require "'+n+'" from "'+t+'"');throw r.path=n,r.parent=t,r.require=!0,r}var o=require.modules[i];if(!o._resolving&&!o.exports){var a={};a.exports={},a.client=a.component=!0,o._resolving=!0,o.call(this,a.exports,require.relative(i),a),delete o._resolving,o.exports=a.exports}return o.exports}if(function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=e.length,n=J.type(e);return"function"!==n&&!J.isWindow(e)&&(!(1!==e.nodeType||!t)||("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e))}function i(e,t,n){if(J.isFunction(t))return J.grep(e,function(e,i){return!!t.call(e,i,e)!==n});if(t.nodeType)return J.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ie.test(t))return J.filter(t,e,n);t=J.filter(t,e)}return J.grep(e,function(e){return z.call(t,e)>=0!==n})}function r(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function o(e){var t=ce[e]={};return J.each(e.match(le)||[],function(e,n){t[n]=!0}),t}function a(){Z.removeEventListener("DOMContentLoaded",a,!1),e.removeEventListener("load",a,!1),J.ready()}function s(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=J.expando+Math.random()}function l(e,t,n){var i;if(void 0===n&&1===e.nodeType)if(i="data-"+t.replace(ge,"-$1").toLowerCase(),"string"==typeof(n=e.getAttribute(i))){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:pe.test(n)?J.parseJSON(n):n)}catch(e){}he.set(e,t,n)}else n=void 0;return n}function c(){return!0}function u(){return!1}function d(){try{return Z.activeElement}catch(e){}}function f(e,t){return J.nodeName(e,"table")&&J.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function h(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function p(e){var t=Me.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function g(e,t){for(var n=0,i=e.length;n")).appendTo(t.documentElement),t=Ie[0].contentDocument,t.write(),t.close(),n=y(e,t),Ie.detach()),Pe[e]=n),n}function w(e,t,n){var i,r,o,a,s=e.style;return n=n||Fe(e),n&&(a=n.getPropertyValue(t)||n[t]),n&&(""!==a||J.contains(e.ownerDocument,e)||(a=J.style(e,t)),je.test(a)&&Ne.test(t)&&(i=s.width,r=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=i,s.minWidth=r,s.maxWidth=o)),void 0!==a?a+"":a}function x(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function C(e,t){if(t in e)return t;for(var n=t[0].toUpperCase()+t.slice(1),i=t,r=Ue.length;r--;)if((t=Ue[r]+n)in e)return t;return i}function k(e,t,n){var i=Re.exec(t);return i?Math.max(0,i[1]-(n||0))+(i[2]||"px"):t}function S(e,t,n,i,r){for(var o=n===(i?"border":"content")?4:"width"===t?1:0,a=0;o<4;o+=2)"margin"===n&&(a+=J.css(e,n+ve[o],!0,r)),i?("content"===n&&(a-=J.css(e,"padding"+ve[o],!0,r)),"margin"!==n&&(a-=J.css(e,"border"+ve[o]+"Width",!0,r))):(a+=J.css(e,"padding"+ve[o],!0,r),"padding"!==n&&(a+=J.css(e,"border"+ve[o]+"Width",!0,r)));return a}function E(e,t,n){var i=!0,r="width"===t?e.offsetWidth:e.offsetHeight,o=Fe(e),a="border-box"===J.css(e,"boxSizing",!1,o);if(r<=0||null==r){if(r=w(e,t,o),(r<0||null==r)&&(r=e.style[t]),je.test(r))return r;i=a&&(X.boxSizingReliable()||r===e.style[t]),r=parseFloat(r)||0}return r+S(e,t,n||(a?"border":"content"),i,o)+"px"}function T(e,t){for(var n,i,r,o=[],a=0,s=e.length;a=0&&n=0},isPlainObject:function(e){return"object"===J.type(e)&&!e.nodeType&&!J.isWindow(e)&&!(e.constructor&&!G.call(e.constructor.prototype,"isPrototypeOf"))},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?Y[K.call(e)]||"object":typeof e},globalEval:function(e){var t,n=eval;(e=J.trim(e))&&(1===e.indexOf("use strict")?(t=Z.createElement("script"),t.text=e,Z.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,Q)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,i){var r=0,o=e.length,a=n(e);if(i){if(a)for(;rb.cacheLength&&delete e[t.shift()],e[n+" "]=i}var t=[];return e}function i(e){return e[L]=!0,e}function r(e){var t=M.createElement("div");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),i=e.length;i--;)b.attrHandle[n[i]]=t}function a(e,t){var n=t&&e,i=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||z)-(~e.sourceIndex||z);if(i)return i;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return i(function(t){return t=+t,i(function(n,i){for(var r,o=e([],n.length,t),a=o.length;a--;)n[r=o[a]]&&(n[r]=!(i[r]=n[r]))})})}function l(e){return e&&typeof e.getElementsByTagName!==W&&e}function c(){}function u(e){for(var t=0,n=e.length,i="";t1?function(t,n,i){for(var r=e.length;r--;)if(!e[r](t,n,i))return!1;return!0}:e[0]}function h(e,n,i){for(var r=0,o=n.length;r-1&&(i[c]=!(a[c]=d))}}else y=p(y===a?y.splice(m,y.length):y),o?o(null,a,y,l):Z.apply(a,y)})}function m(e){for(var t,n,i,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,l=d(function(e){return e===t},a,!0),c=d(function(e){return Q.call(t,e)>-1},a,!0),h=[function(e,n,i){return!o&&(i||n!==E)||((t=n).nodeType?l(e,n,i):c(e,n,i))}];s1&&f(h),s>1&&u(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(ae,"$1"),n,s0,o=e.length>0,a=function(i,a,s,l,c){var u,d,f,h=0,g="0",m=i&&[],v=[],$=E,y=i||o&&b.find.TAG("*",c),w=V+=null==$?1:Math.random()||.1,x=y.length;for(c&&(E=a!==M&&a);g!==x&&null!=(u=y[g]);g++){if(o&&u){for(d=0;f=e[d++];)if(f(u,a,s)){l.push(u);break}c&&(V=w)}r&&((u=!f&&u)&&h--,i&&m.push(u))}if(h+=g,r&&g!==h){for(d=0;f=n[d++];)f(m,v,a,s);if(i){if(h>0)for(;g--;)m[g]||v[g]||(v[g]=G.call(l));v=p(v)}Z.apply(l,v),c&&!i&&v.length>0&&h+n.length>1&&t.uniqueSort(l)}return c&&(V=w,E=$),m};return r?i(a):a}var $,y,b,w,x,C,k,S,E,T,D,A,M,O,I,P,N,j,F,L="sizzle"+-new Date,R=e.document,V=0,H=0,q=n(),U=n(),_=n(),B=function(e,t){return e===t&&(D=!0),0},W="undefined",z=1<<31,Y={}.hasOwnProperty,K=[],G=K.pop,X=K.push,Z=K.push,J=K.slice,Q=K.indexOf||function(e){for(var t=0,n=this.length;t+~]|"+te+")"+te+"*"),ce=new RegExp("="+te+"*([^\\]'\"]*?)"+te+"*\\]","g"),ue=new RegExp(oe),de=new RegExp("^"+ie+"$"),fe={ID:new RegExp("^#("+ne+")"),CLASS:new RegExp("^\\.("+ne+")"),TAG:new RegExp("^("+ne.replace("w","w*")+")"),ATTR:new RegExp("^"+re),PSEUDO:new RegExp("^"+oe),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+te+"*(even|odd|(([+-]|)(\\d*)n|)"+te+"*(?:([+-]|)"+te+"*(\\d+)|))"+te+"*\\)|)","i"),bool:new RegExp("^(?:"+ee+")$","i"),needsContext:new RegExp("^"+te+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+te+"*((?:-\\d)?\\d*)"+te+"*\\)|)(?=[^-]|$)","i")},he=/^(?:input|select|textarea|button)$/i,pe=/^h\d$/i,ge=/^[^{]+\{\s*\[native \w/,me=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,$e=/'|\\/g,ye=new RegExp("\\\\([\\da-f]{1,6}"+te+"?|("+te+")|.)","ig"),be=function(e,t,n){var i="0x"+t-65536;return i!==i||n?t:i<0?String.fromCharCode(i+65536):String.fromCharCode(i>>10|55296,1023&i|56320)};try{Z.apply(K=J.call(R.childNodes),R.childNodes),K[R.childNodes.length].nodeType}catch(e){Z={apply:K.length?function(e,t){X.apply(e,J.call(t))}:function(e,t){for(var n=e.length,i=0;e[n++]=t[i++];);e.length=n-1}}}y=t.support={},x=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},A=t.setDocument=function(e){var t,n=e?e.ownerDocument||e:R,i=n.defaultView;return n!==M&&9===n.nodeType&&n.documentElement?(M=n,O=n.documentElement,I=!x(n),i&&i!==i.top&&(i.addEventListener?i.addEventListener("unload",function(){A()},!1):i.attachEvent&&i.attachEvent("onunload",function(){A()})),y.attributes=r(function(e){return e.className="i",!e.getAttribute("className")}),y.getElementsByTagName=r(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),y.getElementsByClassName=ge.test(n.getElementsByClassName)&&r(function(e){return e.innerHTML="
",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),y.getById=r(function(e){return O.appendChild(e).id=L,!n.getElementsByName||!n.getElementsByName(L).length}),y.getById?(b.find.ID=function(e,t){if(typeof t.getElementById!==W&&I){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},b.filter.ID=function(e){var t=e.replace(ye,be);return function(e){return e.getAttribute("id")===t}}):(delete b.find.ID,b.filter.ID=function(e){var t=e.replace(ye,be);return function(e){var n=typeof e.getAttributeNode!==W&&e.getAttributeNode("id");return n&&n.value===t}}),b.find.TAG=y.getElementsByTagName?function(e,t){if(typeof t.getElementsByTagName!==W)return t.getElementsByTagName(e)}:function(e,t){var n,i=[],r=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[r++];)1===n.nodeType&&i.push(n);return i}return o},b.find.CLASS=y.getElementsByClassName&&function(e,t){if(typeof t.getElementsByClassName!==W&&I)return t.getElementsByClassName(e)},N=[],P=[],(y.qsa=ge.test(n.querySelectorAll))&&(r(function(e){e.innerHTML="",e.querySelectorAll("[msallowclip^='']").length&&P.push("[*^$]="+te+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||P.push("\\["+te+"*(?:value|"+ee+")"),e.querySelectorAll(":checked").length||P.push(":checked")}),r(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&P.push("name"+te+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||P.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),P.push(",.*:")})),(y.matchesSelector=ge.test(j=O.matches||O.webkitMatchesSelector||O.mozMatchesSelector||O.oMatchesSelector||O.msMatchesSelector))&&r(function(e){y.disconnectedMatch=j.call(e,"div"),j.call(e,"[s!='']:x"),N.push("!=",oe)}),P=P.length&&new RegExp(P.join("|")),N=N.length&&new RegExp(N.join("|")),t=ge.test(O.compareDocumentPosition),F=t||ge.test(O.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,i=t&&t.parentNode;return e===i||!(!i||1!==i.nodeType||!(n.contains?n.contains(i):e.compareDocumentPosition&&16&e.compareDocumentPosition(i)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},B=t?function(e,t){if(e===t)return D=!0,0;var i=!e.compareDocumentPosition-!t.compareDocumentPosition;return i?i:(i=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&i||!y.sortDetached&&t.compareDocumentPosition(e)===i?e===n||e.ownerDocument===R&&F(R,e)?-1:t===n||t.ownerDocument===R&&F(R,t)?1:T?Q.call(T,e)-Q.call(T,t):0:4&i?-1:1)}:function(e,t){if(e===t)return D=!0,0;var i,r=0,o=e.parentNode,s=t.parentNode,l=[e],c=[t];if(!o||!s)return e===n?-1:t===n?1:o?-1:s?1:T?Q.call(T,e)-Q.call(T,t):0;if(o===s)return a(e,t);for(i=e;i=i.parentNode;)l.unshift(i);for(i=t;i=i.parentNode;)c.unshift(i);for(;l[r]===c[r];)r++;return r?a(l[r],c[r]):l[r]===R?-1:c[r]===R?1:0},n):M},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==M&&A(e),n=n.replace(ce,"='$1']"),y.matchesSelector&&I&&(!N||!N.test(n))&&(!P||!P.test(n)))try{var i=j.call(e,n);if(i||y.disconnectedMatch||e.document&&11!==e.document.nodeType)return i}catch(e){}return t(n,M,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==M&&A(e),F(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==M&&A(e);var n=b.attrHandle[t.toLowerCase()],i=n&&Y.call(b.attrHandle,t.toLowerCase())?n(e,t,!I):void 0;return void 0!==i?i:y.attributes||!I?e.getAttribute(t):(i=e.getAttributeNode(t))&&i.specified?i.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],i=0,r=0;if(D=!y.detectDuplicates,T=!y.sortStable&&e.slice(0),e.sort(B),D){for(;t=e[r++];)t===e[r]&&(i=n.push(r));for(;i--;)e.splice(n[i],1)}return T=null,e},w=t.getText=function(e){var t,n="",i=0,r=e.nodeType;if(r){if(1===r||9===r||11===r){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=w(e)}else if(3===r||4===r)return e.nodeValue}else for(;t=e[i++];)n+=w(t);return n},b=t.selectors={cacheLength:50,createPseudo:i,match:fe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(ye,be),e[3]=(e[3]||e[4]||e[5]||"").replace(ye,be),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return fe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&ue.test(n)&&(t=C(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(ye,be).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=q[e+" "];return t||(t=new RegExp("(^|"+te+")"+e+"("+te+"|$)"))&&q(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==W&&e.getAttribute("class")||"")})},ATTR:function(e,n,i){return function(r){var o=t.attr(r,e);return null==o?"!="===n:!n||(o+="","="===n?o===i:"!="===n?o!==i:"^="===n?i&&0===o.indexOf(i):"*="===n?i&&o.indexOf(i)>-1:"$="===n?i&&o.slice(-i.length)===i:"~="===n?(" "+o+" ").indexOf(i)>-1:"|="===n&&(o===i||o.slice(0,i.length+1)===i+"-"))}},CHILD:function(e,t,n,i,r){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===i&&0===r?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,f,h,p,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,v=s&&t.nodeName.toLowerCase(),$=!l&&!s;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;p=g="only"===e&&!p&&"nextSibling"}return!0}if(p=[a?m.firstChild:m.lastChild],a&&$){for(u=m[L]||(m[L]={}),c=u[e]||[],h=c[0]===V&&c[1],f=c[0]===V&&c[2],d=h&&m.childNodes[h];d=++h&&d&&d[g]||(f=h=0)||p.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[V,h,f];break}}else if($&&(c=(t[L]||(t[L]={}))[e])&&c[0]===V)f=c[1];else for(;(d=++h&&d&&d[g]||(f=h=0)||p.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++f||($&&((d[L]||(d[L]={}))[e]=[V,f]),d!==t)););return(f-=r)===i||f%i==0&&f/i>=0}}},PSEUDO:function(e,n){var r,o=b.pseudos[e]||b.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[L]?o(n):o.length>1?(r=[e,e,"",n],b.setFilters.hasOwnProperty(e.toLowerCase())?i(function(e,t){for(var i,r=o(e,n),a=r.length;a--;)i=Q.call(e,r[a]),e[i]=!(t[i]=r[a])}):function(e){return o(e,0,r)}):o}},pseudos:{not:i(function(e){var t=[],n=[],r=k(e.replace(ae,"$1"));return r[L]?i(function(e,t,n,i){for(var o,a=r(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:i(function(e){return function(n){return t(e,n).length>0}}),contains:i(function(e){return function(t){return(t.textContent||t.innerText||w(t)).indexOf(e)>-1}}),lang:i(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(ye,be).toLowerCase(),function(t){var n;do{if(n=I?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===O},focus:function(e){return e===M.activeElement&&(!M.hasFocus||M.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return pe.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:s(function(){return[0]}),last:s(function(e,t){return[t-1]}),eq:s(function(e,t,n){return[n<0?n+t:n]}),even:s(function(e,t){for(var n=0;n=0;)e.push(i);return e}),gt:s(function(e,t,n){for(var i=n<0?n+t:n;++i2&&"ID"===(a=o[0]).type&&y.getById&&9===t.nodeType&&I&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(ye,be),t)||[])[0]))return n;d&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(r=fe.needsContext.test(e)?0:o.length;r--&&(a=o[r],!b.relative[s=a.type]);)if((c=b.find[s])&&(i=c(a.matches[0].replace(ye,be),ve.test(o[0].type)&&l(t.parentNode)||t))){if(o.splice(r,1),!(e=i.length&&u(o)))return Z.apply(n,i),n;break}}return(d||k(e,f))(i,t,!I,n,ve.test(e)&&l(t.parentNode)||t),n},y.sortStable=L.split("").sort(B).join("")===L,y.detectDuplicates=!!D,A(),y.sortDetached=r(function(e){return 1&e.compareDocumentPosition(M.createElement("div"))}),r(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),y.attributes&&r(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),r(function(e){return null==e.getAttribute("disabled")})||o(ee,function(e,t,n){var i;if(!n)return e[t]===!0?t.toLowerCase():(i=e.getAttributeNode(t))&&i.specified?i.value:null}),t}(e);J.find=ee,J.expr=ee.selectors,J.expr[":"]=J.expr.pseudos,J.unique=ee.uniqueSort,J.text=ee.getText,J.isXMLDoc=ee.isXML,J.contains=ee.contains;var te=J.expr.match.needsContext,ne=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,ie=/^.[^:#\[\.,]*$/;J.filter=function(e,t,n){ +var i=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===i.nodeType?J.find.matchesSelector(i,e)?[i]:[]:J.find.matches(e,J.grep(t,function(e){return 1===e.nodeType}))},J.fn.extend({find:function(e){var t,n=this.length,i=[],r=this;if("string"!=typeof e)return this.pushStack(J(e).filter(function(){for(t=0;t1?J.unique(i):i),i.selector=this.selector?this.selector+" "+e:e,i},filter:function(e){return this.pushStack(i(this,e||[],!1))},not:function(e){return this.pushStack(i(this,e||[],!0))},is:function(e){return!!i(this,"string"==typeof e&&te.test(e)?J(e):e||[],!1).length}});var re,oe=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;(J.fn.init=function(e,t){var n,i;if(!e)return this;if("string"==typeof e){if(!(n="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:oe.exec(e))||!n[1]&&t)return!t||t.jquery?(t||re).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof J?t[0]:t,J.merge(this,J.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:Z,!0)),ne.test(n[1])&&J.isPlainObject(t))for(n in t)J.isFunction(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}return i=Z.getElementById(n[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=Z,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):J.isFunction(e)?void 0!==re.ready?re.ready(e):e(J):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),J.makeArray(e,this))}).prototype=J.fn,re=J(Z);var ae=/^(?:parents|prev(?:Until|All))/,se={children:!0,contents:!0,next:!0,prev:!0};J.extend({dir:function(e,t,n){for(var i=[],r=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(r&&J(e).is(n))break;i.push(e)}return i},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}}),J.fn.extend({has:function(e){var t=J(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&J.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?J.unique(o):o)},index:function(e){return e?"string"==typeof e?z.call(J(e),this[0]):z.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(J.unique(J.merge(this.get(),J(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),J.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return J.dir(e,"parentNode")},parentsUntil:function(e,t,n){return J.dir(e,"parentNode",n)},next:function(e){return r(e,"nextSibling")},prev:function(e){return r(e,"previousSibling")},nextAll:function(e){return J.dir(e,"nextSibling")},prevAll:function(e){return J.dir(e,"previousSibling")},nextUntil:function(e,t,n){return J.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return J.dir(e,"previousSibling",n)},siblings:function(e){return J.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return J.sibling(e.firstChild)},contents:function(e){return e.contentDocument||J.merge([],e.childNodes)}},function(e,t){J.fn[e]=function(n,i){var r=J.map(this,t,n);return"Until"!==e.slice(-5)&&(i=n),i&&"string"==typeof i&&(r=J.filter(i,r)),this.length>1&&(se[e]||J.unique(r),ae.test(e)&&r.reverse()),this.pushStack(r)}});var le=/\S+/g,ce={};J.Callbacks=function(e){e="string"==typeof e?ce[e]||o(e):J.extend({},e);var t,n,i,r,a,s,l=[],c=!e.once&&[],u=function(o){for(t=e.memory&&o,n=!0,s=r||0,r=0,a=l.length,i=!0;l&&s-1;)l.splice(n,1),i&&(n<=a&&a--,n<=s&&s--)}),this},has:function(e){return e?J.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],a=0,this},disable:function(){return l=c=t=void 0,this},disabled:function(){return!l},lock:function(){return c=void 0,t||d.disable(),this},locked:function(){return!c},fireWith:function(e,t){return!l||n&&!c||(t=t||[],t=[e,t.slice?t.slice():t],i?c.push(t):u(t)),this},fire:function(){return d.fireWith(this,arguments),this},fired:function(){return!!n}};return d},J.extend({Deferred:function(e){var t=[["resolve","done",J.Callbacks("once memory"),"resolved"],["reject","fail",J.Callbacks("once memory"),"rejected"],["notify","progress",J.Callbacks("memory")]],n="pending",i={state:function(){return n},always:function(){return r.done(arguments).fail(arguments),this},then:function(){var e=arguments;return J.Deferred(function(n){J.each(t,function(t,o){var a=J.isFunction(e[t])&&e[t];r[o[1]](function(){var e=a&&a.apply(this,arguments);e&&J.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[o[0]+"With"](this===i?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?J.extend(e,i):i}},r={};return i.pipe=i.then,J.each(t,function(e,o){var a=o[2],s=o[3];i[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),r[o[0]]=function(){return r[o[0]+"With"](this===r?i:this,arguments),this},r[o[0]+"With"]=a.fireWith}),i.promise(r),e&&e.call(r,r),r},when:function(e){var t,n,i,r=0,o=_.call(arguments),a=o.length,s=1!==a||e&&J.isFunction(e.promise)?a:0,l=1===s?e:J.Deferred(),c=function(e,n,i){return function(r){n[e]=this,i[e]=arguments.length>1?_.call(arguments):r,i===t?l.notifyWith(n,i):--s||l.resolveWith(n,i)}};if(a>1)for(t=new Array(a),n=new Array(a),i=new Array(a);r0||(ue.resolveWith(Z,[J]),J.fn.triggerHandler&&(J(Z).triggerHandler("ready"),J(Z).off("ready"))))}}),J.ready.promise=function(t){return ue||(ue=J.Deferred(),"complete"===Z.readyState?setTimeout(J.ready):(Z.addEventListener("DOMContentLoaded",a,!1),e.addEventListener("load",a,!1))),ue.promise(t)},J.ready.promise();var de=J.access=function(e,t,n,i,r,o,a){var s=0,l=e.length,c=null==n;if("object"===J.type(n)){r=!0;for(s in n)J.access(e,t,s,n[s],!0,o,a)}else if(void 0!==i&&(r=!0,J.isFunction(i)||(a=!0),c&&(a?(t.call(e,i),t=null):(c=t,t=function(e,t,n){return c.call(J(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){he.remove(this,e)})}}),J.extend({queue:function(e,t,n){var i;if(e)return t=(t||"fx")+"queue",i=fe.get(e,t),n&&(!i||J.isArray(n)?i=fe.access(e,t,J.makeArray(n)):i.push(n)),i||[]},dequeue:function(e,t){t=t||"fx";var n=J.queue(e,t),i=n.length,r=n.shift(),o=J._queueHooks(e,t),a=function(){J.dequeue(e,t)};"inprogress"===r&&(r=n.shift(),i--),r&&("fx"===t&&n.unshift("inprogress"),delete o.stop,r.call(e,a,o)),!i&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return fe.get(e,n)||fe.access(e,n,{empty:J.Callbacks("once memory").add(function(){fe.remove(e,[t+"queue",n])})})}}),J.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.lengthx",X.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue}();X.focusinBubbles="onfocusin"in e;var be=/^key/,we=/^(?:mouse|pointer|contextmenu)|click/,xe=/^(?:focusinfocus|focusoutblur)$/,Ce=/^([^.]*)(?:\.(.+)|)$/;J.event={global:{},add:function(e,t,n,i,r){var o,a,s,l,c,u,d,f,h,p,g,m=fe.get(e);if(m)for(n.handler&&(o=n,n=o.handler,r=o.selector),n.guid||(n.guid=J.guid++),(l=m.events)||(l=m.events={}),(a=m.handle)||(a=m.handle=function(t){return void 0!==J&&J.event.triggered!==t.type?J.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(le)||[""],c=t.length;c--;)s=Ce.exec(t[c])||[],h=g=s[1],p=(s[2]||"").split(".").sort(),h&&(d=J.event.special[h]||{},h=(r?d.delegateType:d.bindType)||h,d=J.event.special[h]||{},u=J.extend({type:h,origType:g,data:i,handler:n,guid:n.guid,selector:r,needsContext:r&&J.expr.match.needsContext.test(r),namespace:p.join(".")},o),(f=l[h])||(f=l[h]=[],f.delegateCount=0,d.setup&&d.setup.call(e,i,p,a)!==!1||e.addEventListener&&e.addEventListener(h,a,!1)),d.add&&(d.add.call(e,u),u.handler.guid||(u.handler.guid=n.guid)),r?f.splice(f.delegateCount++,0,u):f.push(u),J.event.global[h]=!0)},remove:function(e,t,n,i,r){var o,a,s,l,c,u,d,f,h,p,g,m=fe.hasData(e)&&fe.get(e);if(m&&(l=m.events)){for(t=(t||"").match(le)||[""],c=t.length;c--;)if(s=Ce.exec(t[c])||[],h=g=s[1],p=(s[2]||"").split(".").sort(),h){for(d=J.event.special[h]||{},h=(i?d.delegateType:d.bindType)||h,f=l[h]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=f.length;o--;)u=f[o],!r&&g!==u.origType||n&&n.guid!==u.guid||s&&!s.test(u.namespace)||i&&i!==u.selector&&("**"!==i||!u.selector)||(f.splice(o,1),u.selector&&f.delegateCount--,d.remove&&d.remove.call(e,u));a&&!f.length&&(d.teardown&&d.teardown.call(e,p,m.handle)!==!1||J.removeEvent(e,h,m.handle),delete l[h])}else for(h in l)J.event.remove(e,h+t[c],n,i,!0);J.isEmptyObject(l)&&(delete m.handle,fe.remove(e,"events"))}},trigger:function(t,n,i,r){var o,a,s,l,c,u,d,f=[i||Z],h=G.call(t,"type")?t.type:t,p=G.call(t,"namespace")?t.namespace.split("."):[];if(a=s=i=i||Z,3!==i.nodeType&&8!==i.nodeType&&!xe.test(h+J.event.triggered)&&(h.indexOf(".")>=0&&(p=h.split("."),h=p.shift(),p.sort()),c=h.indexOf(":")<0&&"on"+h,t=t[J.expando]?t:new J.Event(h,"object"==typeof t&&t),t.isTrigger=r?2:3,t.namespace=p.join("."),t.namespace_re=t.namespace?new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:J.makeArray(n,[t]),d=J.event.special[h]||{},r||!d.trigger||d.trigger.apply(i,n)!==!1)){if(!r&&!d.noBubble&&!J.isWindow(i)){for(l=d.delegateType||h,xe.test(l+h)||(a=a.parentNode);a;a=a.parentNode)f.push(a),s=a;s===(i.ownerDocument||Z)&&f.push(s.defaultView||s.parentWindow||e)}for(o=0;(a=f[o++])&&!t.isPropagationStopped();)t.type=o>1?l:d.bindType||h,u=(fe.get(a,"events")||{})[t.type]&&fe.get(a,"handle"),u&&u.apply(a,n),(u=c&&a[c])&&u.apply&&J.acceptData(a)&&(t.result=u.apply(a,n),t.result===!1&&t.preventDefault());return t.type=h,r||t.isDefaultPrevented()||d._default&&d._default.apply(f.pop(),n)!==!1||!J.acceptData(i)||c&&J.isFunction(i[h])&&!J.isWindow(i)&&(s=i[c],s&&(i[c]=null),J.event.triggered=h,i[h](),J.event.triggered=void 0,s&&(i[c]=s)),t.result}},dispatch:function(e){e=J.event.fix(e);var t,n,i,r,o,a=[],s=_.call(arguments),l=(fe.get(this,"events")||{})[e.type]||[],c=J.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){for(a=J.event.handlers.call(this,e,l),t=0;(r=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=r.elem,n=0;(o=r.handlers[n++])&&!e.isImmediatePropagationStopped();)e.namespace_re&&!e.namespace_re.test(o.namespace)||(e.handleObj=o,e.data=o.data,void 0!==(i=((J.event.special[o.origType]||{}).handle||o.handler).apply(r.elem,s))&&(e.result=i)===!1&&(e.preventDefault(),e.stopPropagation()));return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,i,r,o,a=[],s=t.delegateCount,l=e.target;if(s&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!==this;l=l.parentNode||this)if(l.disabled!==!0||"click"!==e.type){for(i=[],n=0;n=0:J.find(r,this,null,[l]).length),i[r]&&i.push(o);i.length&&a.push({elem:l,handlers:i})}return s]*)\/>/gi,Se=/<([\w:]+)/,Ee=/<|&#?\w+;/,Te=/<(?:script|style|link)/i,De=/checked\s*(?:[^=]|=\s*.checked.)/i,Ae=/^$|\/(?:java|ecma)script/i,Me=/^true\/(.*)/,Oe={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};Oe.optgroup=Oe.option,Oe.tbody=Oe.tfoot=Oe.colgroup=Oe.caption=Oe.thead,Oe.th=Oe.td,J.extend({clone:function(e,t,n){var i,r,o,a,s=e.cloneNode(!0),l=J.contains(e.ownerDocument,e);if(!(X.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||J.isXMLDoc(e)))for(a=v(s),o=v(e),i=0,r=o.length;i0&&g(a,!l&&v(e,"script")),s},buildFragment:function(e,t,n,i){for(var r,o,a,s,l,c,u=t.createDocumentFragment(),d=[],f=0,h=e.length;f")+s[2],c=s[0];c--;)o=o.lastChild;J.merge(d,o.childNodes),o=u.firstChild,o.textContent=""}else d.push(t.createTextNode(r));for(u.textContent="",f=0;r=d[f++];)if((!i||J.inArray(r,i)===-1)&&(l=J.contains(r.ownerDocument,r),o=v(u.appendChild(r),"script"),l&&g(o),n))for(c=0;r=o[c++];)Ae.test(r.type||"")&&n.push(r);return u},cleanData:function(e){for(var t,n,i,r,o=J.event.special,a=0;void 0!==(n=e[a]);a++){if(J.acceptData(n)&&(r=n[fe.expando])&&(t=fe.cache[r])){if(t.events)for(i in t.events)o[i]?J.event.remove(n,i):J.removeEvent(n,i,t.handle);fe.cache[r]&&delete fe.cache[r]}delete he.cache[n[he.expando]]}}}),J.fn.extend({text:function(e){return de(this,function(e){return void 0===e?J.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){f(this,e).appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=f(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){for(var n,i=e?J.filter(e,this):this,r=0;null!=(n=i[r]);r++)t||1!==n.nodeType||J.cleanData(v(n)),n.parentNode&&(t&&J.contains(n.ownerDocument,n)&&g(v(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(J.cleanData(v(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return J.clone(this,e,t)})},html:function(e){return de(this,function(e){var t=this[0]||{},n=0,i=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Te.test(e)&&!Oe[(Se.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(ke,"<$1>");try{for(;n1&&"string"==typeof f&&!X.checkClone&&De.test(f))return this.each(function(n){var i=u.eq(n);g&&(e[0]=f.call(this,n,i.html())),i.domManip(e,t)});if(c&&(n=J.buildFragment(e,this[0].ownerDocument,!1,this),i=n.firstChild,1===n.childNodes.length&&(n=i),i)){for(r=J.map(v(n,"script"),h),o=r.length;l\s*$/g,"")))}return this}}),J.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){J.fn[e]=function(e){for(var n,i=[],r=J(e),o=r.length-1,a=0;a<=o;a++)n=a===o?this:this.clone(!0),J(r[a])[t](n),W.apply(i,n.get());return this.pushStack(i)}});var Ie,Pe={},Ne=/^margin/,je=new RegExp("^("+me+")(?!px)[a-z%]+$","i"),Fe=function(e){return e.ownerDocument.defaultView.getComputedStyle(e,null)};!function(){function t(){a.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",a.innerHTML="",r.appendChild(o);var t=e.getComputedStyle(a,null);n="1%"!==t.top,i="4px"===t.width,r.removeChild(o)}var n,i,r=Z.documentElement,o=Z.createElement("div"),a=Z.createElement("div");a.style&&(a.style.backgroundClip="content-box",a.cloneNode(!0).style.backgroundClip="",X.clearCloneStyle="content-box"===a.style.backgroundClip,o.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",o.appendChild(a),e.getComputedStyle&&J.extend(X,{pixelPosition:function(){return t(),n},boxSizingReliable:function(){return null==i&&t(),i},reliableMarginRight:function(){var t,n=a.appendChild(Z.createElement("div"));return n.style.cssText=a.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",n.style.marginRight=n.style.width="0",a.style.width="1px",r.appendChild(o),t=!parseFloat(e.getComputedStyle(n,null).marginRight),r.removeChild(o),t}}))}(),J.swap=function(e,t,n,i){var r,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];r=n.apply(e,i||[]);for(o in t)e.style[o]=a[o];return r};var Le=/^(none|table(?!-c[ea]).+)/,Re=new RegExp("^("+me+")(.*)$","i"),Ve=new RegExp("^([+-])=("+me+")","i"),He={position:"absolute",visibility:"hidden",display:"block"},qe={letterSpacing:"0",fontWeight:"400"},Ue=["Webkit","O","Moz","ms"];J.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=w(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{float:"cssFloat"},style:function(e,t,n,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var r,o,a,s=J.camelCase(t),l=e.style;if(t=J.cssProps[s]||(J.cssProps[s]=C(l,s)),a=J.cssHooks[t]||J.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(r=a.get(e,!1,i))?r:l[t];o=typeof n,"string"===o&&(r=Ve.exec(n))&&(n=(r[1]+1)*r[2]+parseFloat(J.css(e,t)),o="number"),null!=n&&n===n&&("number"!==o||J.cssNumber[s]||(n+="px"),X.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,i))||(l[t]=n))}},css:function(e,t,n,i){var r,o,a,s=J.camelCase(t);return t=J.cssProps[s]||(J.cssProps[s]=C(e.style,s)),a=J.cssHooks[t]||J.cssHooks[s],a&&"get"in a&&(r=a.get(e,!0,n)),void 0===r&&(r=w(e,t,i)),"normal"===r&&t in qe&&(r=qe[t]),""===n||n?(o=parseFloat(r),n===!0||J.isNumeric(o)?o||0:r):r}}),J.each(["height","width"],function(e,t){J.cssHooks[t]={get:function(e,n,i){if(n)return Le.test(J.css(e,"display"))&&0===e.offsetWidth?J.swap(e,He,function(){return E(e,t,i)}):E(e,t,i)},set:function(e,n,i){var r=i&&Fe(e);return k(e,n,i?S(e,t,i,"border-box"===J.css(e,"boxSizing",!1,r),r):0)}}}),J.cssHooks.marginRight=x(X.reliableMarginRight,function(e,t){if(t)return J.swap(e,{display:"inline-block"},w,[e,"marginRight"])}),J.each({margin:"",padding:"",border:"Width"},function(e,t){J.cssHooks[e+t]={expand:function(n){for(var i=0,r={},o="string"==typeof n?n.split(" "):[n];i<4;i++)r[e+ve[i]+t]=o[i]||o[i-2]||o[0];return r}},Ne.test(e)||(J.cssHooks[e+t].set=k)}),J.fn.extend({css:function(e,t){return de(this,function(e,t,n){var i,r,o={},a=0;if(J.isArray(t)){for(i=Fe(e),r=t.length;a1)},show:function(){return T(this,!0)},hide:function(){return T(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){$e(this)?J(this).show():J(this).hide()})}}),J.Tween=D,D.prototype={constructor:D,init:function(e,t,n,i,r,o){this.elem=e,this.prop=n,this.easing=r||"swing",this.options=t,this.start=this.now=this.cur(),this.end=i,this.unit=o||(J.cssNumber[n]?"":"px")},cur:function(){var e=D.propHooks[this.prop];return e&&e.get?e.get(this):D.propHooks._default.get(this)},run:function(e){var t,n=D.propHooks[this.prop];return this.options.duration?this.pos=t=J.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):D.propHooks._default.set(this),this}},D.prototype.init.prototype=D.prototype,D.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=J.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){J.fx.step[e.prop]?J.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[J.cssProps[e.prop]]||J.cssHooks[e.prop])?J.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},D.propHooks.scrollTop=D.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},J.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},J.fx=D.prototype.init,J.fx.step={};var _e,Be,We=/^(?:toggle|show|hide)$/,ze=new RegExp("^(?:([+-])=|)("+me+")([a-z%]*)$","i"),Ye=/queueHooks$/,Ke=[I],Ge={"*":[function(e,t){var n=this.createTween(e,t),i=n.cur(),r=ze.exec(t),o=r&&r[3]||(J.cssNumber[e]?"":"px"),a=(J.cssNumber[e]||"px"!==o&&+i)&&ze.exec(J.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],r=r||[],a=+i||1;do{s=s||".5",a/=s,J.style(n.elem,e,a+o)}while(s!==(s=n.cur()/i)&&1!==s&&--l)}return r&&(a=n.start=+a||+i||0,n.unit=o,n.end=r[1]?a+(r[1]+1)*r[2]:+r[2]),n}]};J.Animation=J.extend(N,{tweener:function(e,t){J.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");for(var n,i=0,r=e.length;i1)},removeAttr:function(e){return this.each(function(){J.removeAttr(this,e)})}}),J.extend({attr:function(e,t,n){var i,r,o=e.nodeType;if(e&&3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?J.prop(e,t,n):(1===o&&J.isXMLDoc(e)||(t=t.toLowerCase(),i=J.attrHooks[t]||(J.expr.match.bool.test(t)?Xe:void 0)),void 0===n?i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=J.find.attr(e,t),null==r?void 0:r):null!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):void J.removeAttr(e,t))},removeAttr:function(e,t){var n,i,r=0,o=t&&t.match(le);if(o&&1===e.nodeType)for(;n=o[r++];)i=J.propFix[n]||n,J.expr.match.bool.test(n)&&(e[i]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!X.radioValue&&"radio"===t&&J.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}}}),Xe={set:function(e,t,n){return t===!1?J.removeAttr(e,n):e.setAttribute(n,n),n}},J.each(J.expr.match.bool.source.match(/\w+/g),function(e,t){var n=Ze[t]||J.find.attr;Ze[t]=function(e,t,i){var r,o;return i||(o=Ze[t],Ze[t]=r,r=null!=n(e,t,i)?t.toLowerCase():null,Ze[t]=o),r}});var Je=/^(?:input|select|textarea|button)$/i;J.fn.extend({prop:function(e,t){return de(this,J.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[J.propFix[e]||e]})}}),J.extend({propFix:{for:"htmlFor",class:"className"},prop:function(e,t,n){var i,r,o,a=e.nodeType;if(e&&3!==a&&8!==a&&2!==a)return o=1!==a||!J.isXMLDoc(e),o&&(t=J.propFix[t]||t,r=J.propHooks[t]),void 0!==n?r&&"set"in r&&void 0!==(i=r.set(e,n,t))?i:e[t]=n:r&&"get"in r&&null!==(i=r.get(e,t))?i:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||Je.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),X.optSelected||(J.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),J.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){J.propFix[this.toLowerCase()]=this});J.fn.extend({addClass:function(e){var t,n,i,r,o,a,s="string"==typeof e&&e,l=0,c=this.length;if(J.isFunction(e))return this.each(function(t){J(this).addClass(e.call(this,t,this.className))});if(s)for(t=(e||"").match(le)||[];l=0;)i=i.replace(" "+r+" "," ");a=e?J.trim(i):"",n.className!==a&&(n.className=a)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):J.isFunction(e)?this.each(function(n){J(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n)for(var t,i=0,r=J(this),o=e.match(le)||[];t=o[i++];)r.hasClass(t)?r.removeClass(t):r.addClass(t);else"undefined"!==n&&"boolean"!==n||(this.className&&fe.set(this,"__className__",this.className),this.className=this.className||e===!1?"":fe.get(this,"__className__")||"")})},hasClass:function(e){for(var t=" "+e+" ",n=0,i=this.length;n=0)return!0;return!1}});J.fn.extend({val:function(e){var t,n,i,r=this[0];{if(arguments.length)return i=J.isFunction(e),this.each(function(n){var r;1===this.nodeType&&(r=i?e.call(this,n,J(this).val()):e,null==r?r="":"number"==typeof r?r+="":J.isArray(r)&&(r=J.map(r,function(e){return null==e?"":e+""})),(t=J.valHooks[this.type]||J.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,r,"value")||(this.value=r))});if(r)return(t=J.valHooks[r.type]||J.valHooks[r.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(r,"value"))?n:(n=r.value,"string"==typeof n?n.replace(/\r/g,""):null==n?"":n)}}}),J.extend({valHooks:{option:{get:function(e){var t=J.find.attr(e,"value");return null!=t?t:J.trim(J.text(e))}},select:{get:function(e){for(var t,n,i=e.options,r=e.selectedIndex,o="select-one"===e.type||r<0,a=o?null:[],s=o?r+1:i.length,l=r<0?s:o?r:0;l=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),J.each(["radio","checkbox"],function(){J.valHooks[this]={set:function(e,t){if(J.isArray(t))return e.checked=J.inArray(J(e).val(),t)>=0}},X.checkOn||(J.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),J.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){J.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),J.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,i){return this.on(t,e,n,i)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var Qe=J.now(),et=/\?/;J.parseJSON=function(e){return JSON.parse(e+"")},J.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||J.error("Invalid XML: "+e),t};var tt,nt,it=/([?&])_=[^&]*/,rt=/^(.*?):[ \t]*([^\r\n]*)$/gm,ot=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,at=/^(?:GET|HEAD)$/,st=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lt={},ct={},ut="*/".concat("*");try{nt=location.href}catch(e){nt=Z.createElement("a"),nt.href="",nt=nt.href}tt=st.exec(nt.toLowerCase())||[],J.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:nt,type:"GET",isLocal:ot.test(tt[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":ut,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":J.parseJSON,"text xml":J.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?L(L(e,J.ajaxSettings),t):L(J.ajaxSettings,e)},ajaxPrefilter:j(lt),ajaxTransport:j(ct),ajax:function(e,t){function n(e,t,n,a){var l,u,v,$,b,x=t;2!==y&&(y=2,s&&clearTimeout(s),i=void 0,o=a||"",w.readyState=e>0?4:0,l=e>=200&&e<300||304===e,n&&($=R(d,w,n)),$=V(d,$,w,l),l?(d.ifModified&&(b=w.getResponseHeader("Last-Modified"),b&&(J.lastModified[r]=b),(b=w.getResponseHeader("etag"))&&(J.etag[r]=b)),204===e||"HEAD"===d.type?x="nocontent":304===e?x="notmodified":(x=$.state,u=$.data,v=$.error,l=!v)):(v=x,!e&&x||(x="error",e<0&&(e=0))),w.status=e,w.statusText=(t||x)+"",l?p.resolveWith(f,[u,x,w]):p.rejectWith(f,[w,x,v]),w.statusCode(m),m=void 0,c&&h.trigger(l?"ajaxSuccess":"ajaxError",[w,d,l?u:v]),g.fireWith(f,[w,x]),c&&(h.trigger("ajaxComplete",[w,d]),--J.active||J.event.trigger("ajaxStop")))}"object"==typeof e&&(t=e,e=void 0),t=t||{};var i,r,o,a,s,l,c,u,d=J.ajaxSetup({},t),f=d.context||d,h=d.context&&(f.nodeType||f.jquery)?J(f):J.event,p=J.Deferred(),g=J.Callbacks("once memory"),m=d.statusCode||{},v={},$={},y=0,b="canceled",w={readyState:0,getResponseHeader:function(e){var t;if(2===y){if(!a)for(a={};t=rt.exec(o);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===y?o:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return y||(e=$[n]=$[n]||e,v[e]=t),this},overrideMimeType:function(e){return y||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(y<2)for(t in e)m[t]=[m[t],e[t]];else w.always(e[w.status]);return this},abort:function(e){var t=e||b;return i&&i.abort(t),n(0,t),this}};if(p.promise(w).complete=g.add,w.success=w.done,w.error=w.fail,d.url=((e||d.url||nt)+"").replace(/#.*$/,"").replace(/^\/\//,tt[1]+"//"),d.type=t.method||t.type||d.method||d.type,d.dataTypes=J.trim(d.dataType||"*").toLowerCase().match(le)||[""],null==d.crossDomain&&(l=st.exec(d.url.toLowerCase()),d.crossDomain=!(!l||l[1]===tt[1]&&l[2]===tt[2]&&(l[3]||("http:"===l[1]?"80":"443"))===(tt[3]||("http:"===tt[1]?"80":"443")))),d.data&&d.processData&&"string"!=typeof d.data&&(d.data=J.param(d.data,d.traditional)),F(lt,d,t,w),2===y)return w;c=d.global,c&&0==J.active++&&J.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!at.test(d.type),r=d.url,d.hasContent||(d.data&&(r=d.url+=(et.test(r)?"&":"?")+d.data,delete d.data),d.cache===!1&&(d.url=it.test(r)?r.replace(it,"$1_="+Qe++):r+(et.test(r)?"&":"?")+"_="+Qe++)),d.ifModified&&(J.lastModified[r]&&w.setRequestHeader("If-Modified-Since",J.lastModified[r]),J.etag[r]&&w.setRequestHeader("If-None-Match",J.etag[r])),(d.data&&d.hasContent&&d.contentType!==!1||t.contentType)&&w.setRequestHeader("Content-Type",d.contentType),w.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+ut+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)w.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(f,w,d)===!1||2===y))return w.abort();b="abort";for(u in{success:1,error:1,complete:1})w[u](d[u]);if(i=F(ct,d,t,w)){w.readyState=1,c&&h.trigger("ajaxSend",[w,d]),d.async&&d.timeout>0&&(s=setTimeout(function(){w.abort("timeout")},d.timeout));try{y=1,i.send(v,n)}catch(e){if(!(y<2))throw e;n(-1,e)}}else n(-1,"No Transport");return w},getJSON:function(e,t,n){return J.get(e,t,n,"json")},getScript:function(e,t){return J.get(e,void 0,t,"script")}}),J.each(["get","post"],function(e,t){J[t]=function(e,n,i,r){return J.isFunction(n)&&(r=r||i,i=n,n=void 0),J.ajax({url:e,type:t,dataType:r,data:n,success:i})}}),J.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){J.fn[t]=function(e){return this.on(t,e)}}),J._evalUrl=function(e){return J.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,throws:!0})},J.fn.extend({wrapAll:function(e){var t;return J.isFunction(e)?this.each(function(t){J(this).wrapAll(e.call(this,t))}):(this[0]&&(t=J(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return J.isFunction(e)?this.each(function(t){J(this).wrapInner(e.call(this,t))}):this.each(function(){var t=J(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=J.isFunction(e);return this.each(function(n){J(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){J.nodeName(this,"body")||J(this).replaceWith(this.childNodes)}).end()}}),J.expr.filters.hidden=function(e){return e.offsetWidth<=0&&e.offsetHeight<=0},J.expr.filters.visible=function(e){return!J.expr.filters.hidden(e)};var dt=/\[\]$/,ft=/^(?:submit|button|image|reset|file)$/i,ht=/^(?:input|select|textarea|keygen)/i;J.param=function(e,t){var n,i=[],r=function(e,t){t=J.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=J.ajaxSettings&&J.ajaxSettings.traditional),J.isArray(e)||e.jquery&&!J.isPlainObject(e))J.each(e,function(){r(this.name,this.value)});else for(n in e)H(n,e[n],t,r);return i.join("&").replace(/%20/g,"+")},J.fn.extend({serialize:function(){return J.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=J.prop(this,"elements");return e?J.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!J(this).is(":disabled")&&ht.test(this.nodeName)&&!ft.test(e)&&(this.checked||!ye.test(e))}).map(function(e,t){var n=J(this).val();return null==n?null:J.isArray(n)?J.map(n,function(e){return{name:t.name,value:e.replace(/\r?\n/g,"\r\n")}}):{name:t.name,value:n.replace(/\r?\n/g,"\r\n")}}).get()}}),J.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var pt=0,gt={},mt={0:200,1223:204},vt=J.ajaxSettings.xhr();e.ActiveXObject&&J(e).on("unload",function(){for(var e in gt)gt[e]()}),X.cors=!!vt&&"withCredentials"in vt,X.ajax=vt=!!vt,J.ajaxTransport(function(e){var t;if(X.cors||vt&&!e.crossDomain)return{send:function(n,i){var r,o=e.xhr(),a=++pt;if(o.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(r in e.xhrFields)o[r]=e.xhrFields[r];e.mimeType&&o.overrideMimeType&&o.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(r in n)o.setRequestHeader(r,n[r]);t=function(e){return function(){t&&(delete gt[a],t=o.onload=o.onerror=null,"abort"===e?o.abort():"error"===e?i(o.status,o.statusText):i(mt[o.status]||o.status,o.statusText,"string"==typeof o.responseText?{text:o.responseText}:void 0,o.getAllResponseHeaders()))}},o.onload=t(),o.onerror=t("error"),t=gt[a]=t("abort");try{o.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}}),J.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return J.globalEval(e),e}}}),J.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),J.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,r){t=J("